Reviewed-by: Pavel Dovgalyuk <Pavel.Dovgalyuk@ispras.ru>
On 18.03.2024 18:46, Nicholas Piggin wrote:
> The regular qemu_bh_schedule() calls result in non-deterministic
> execution of the bh in record-replay mode, which causes replay failure.
>
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
> ---
> hw/net/virtio-net.c | 11 ++++++-----
> 1 file changed, 6 insertions(+), 5 deletions(-)
>
> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> index 9959f1932b..6ac737f2cf 100644
> --- a/hw/net/virtio-net.c
> +++ b/hw/net/virtio-net.c
> @@ -40,6 +40,7 @@
> #include "migration/misc.h"
> #include "standard-headers/linux/ethtool.h"
> #include "sysemu/sysemu.h"
> +#include "sysemu/replay.h"
> #include "trace.h"
> #include "monitor/qdev.h"
> #include "monitor/monitor.h"
> @@ -416,7 +417,7 @@ static void virtio_net_set_status(struct VirtIODevice *vdev, uint8_t status)
> timer_mod(q->tx_timer,
> qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + n->tx_timeout);
> } else {
> - qemu_bh_schedule(q->tx_bh);
> + replay_bh_schedule_event(q->tx_bh);
> }
> } else {
> if (q->tx_timer) {
> @@ -2724,7 +2725,7 @@ static void virtio_net_tx_complete(NetClientState *nc, ssize_t len)
> */
> virtio_queue_set_notification(q->tx_vq, 0);
> if (q->tx_bh) {
> - qemu_bh_schedule(q->tx_bh);
> + replay_bh_schedule_event(q->tx_bh);
> } else {
> timer_mod(q->tx_timer,
> qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + n->tx_timeout);
> @@ -2879,7 +2880,7 @@ static void virtio_net_handle_tx_bh(VirtIODevice *vdev, VirtQueue *vq)
> return;
> }
> virtio_queue_set_notification(vq, 0);
> - qemu_bh_schedule(q->tx_bh);
> + replay_bh_schedule_event(q->tx_bh);
> }
>
> static void virtio_net_tx_timer(void *opaque)
> @@ -2962,7 +2963,7 @@ static void virtio_net_tx_bh(void *opaque)
> /* If we flush a full burst of packets, assume there are
> * more coming and immediately reschedule */
> if (ret >= n->tx_burst) {
> - qemu_bh_schedule(q->tx_bh);
> + replay_bh_schedule_event(q->tx_bh);
> q->tx_waiting = 1;
> return;
> }
> @@ -2976,7 +2977,7 @@ static void virtio_net_tx_bh(void *opaque)
> return;
> } else if (ret > 0) {
> virtio_queue_set_notification(q->tx_vq, 0);
> - qemu_bh_schedule(q->tx_bh);
> + replay_bh_schedule_event(q->tx_bh);
> q->tx_waiting = 1;
> }
> }