Message ID | 20201112094653.20255-1-yuri.benditovich@daynix.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | virtio-net: purge queued rx packets on queue deletion | expand |
On 2020/11/12 下午5:46, Yuri Benditovich wrote: > https://bugzilla.redhat.com/show_bug.cgi?id=1829272 > When deleting queue pair, purge pending RX packets if any. > Example of problematic flow: > 1. Bring up q35 VM with tap (vhost off) and virtio-net or e1000e > 2. Run ping flood to the VM NIC ( 1 ms interval) > 3. Hot unplug the NIC device (device_del) > During unplug process one or more packets come, the NIC > can't receive, tap disables read_poll > 4. Hot plug the device (device_add) with the same netdev > The tap stays with read_poll disabled and does not receive > any packets anymore (tap_send never triggered) > > Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com> Applied. Thanks > --- > net/net.c | 12 ++++++++---- > 1 file changed, 8 insertions(+), 4 deletions(-) > > diff --git a/net/net.c b/net/net.c > index 7a2a0fb5ac..a95b417300 100644 > --- a/net/net.c > +++ b/net/net.c > @@ -411,10 +411,14 @@ void qemu_del_nic(NICState *nic) > > qemu_macaddr_set_free(&nic->conf->macaddr); > > - /* If this is a peer NIC and peer has already been deleted, free it now. */ > - if (nic->peer_deleted) { > - for (i = 0; i < queues; i++) { > - qemu_free_net_client(qemu_get_subqueue(nic, i)->peer); > + for (i = 0; i < queues; i++) { > + NetClientState *nc = qemu_get_subqueue(nic, i); > + /* If this is a peer NIC and peer has already been deleted, free it now. */ > + if (nic->peer_deleted) { > + qemu_free_net_client(nc->peer); > + } else if (nc->peer) { > + /* if there are RX packets pending, complete them */ > + qemu_purge_queued_packets(nc->peer); > } > } >
Hi Jason, Sorry, there is a mistake in the title: should be 'net' instead of 'virtio-net'. Can you please fix it? Thanks, Yuri Benditovich On Wed, Nov 18, 2020 at 5:59 AM Jason Wang <jasowang@redhat.com> wrote: > > On 2020/11/12 下午5:46, Yuri Benditovich wrote: > > https://bugzilla.redhat.com/show_bug.cgi?id=1829272 > > When deleting queue pair, purge pending RX packets if any. > > Example of problematic flow: > > 1. Bring up q35 VM with tap (vhost off) and virtio-net or e1000e > > 2. Run ping flood to the VM NIC ( 1 ms interval) > > 3. Hot unplug the NIC device (device_del) > > During unplug process one or more packets come, the NIC > > can't receive, tap disables read_poll > > 4. Hot plug the device (device_add) with the same netdev > > The tap stays with read_poll disabled and does not receive > > any packets anymore (tap_send never triggered) > > > > Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com> > > > Applied. > > Thanks > > > > --- > > net/net.c | 12 ++++++++---- > > 1 file changed, 8 insertions(+), 4 deletions(-) > > > > diff --git a/net/net.c b/net/net.c > > index 7a2a0fb5ac..a95b417300 100644 > > --- a/net/net.c > > +++ b/net/net.c > > @@ -411,10 +411,14 @@ void qemu_del_nic(NICState *nic) > > > > qemu_macaddr_set_free(&nic->conf->macaddr); > > > > - /* If this is a peer NIC and peer has already been deleted, free it > now. */ > > - if (nic->peer_deleted) { > > - for (i = 0; i < queues; i++) { > > - qemu_free_net_client(qemu_get_subqueue(nic, i)->peer); > > + for (i = 0; i < queues; i++) { > > + NetClientState *nc = qemu_get_subqueue(nic, i); > > + /* If this is a peer NIC and peer has already been deleted, > free it now. */ > > + if (nic->peer_deleted) { > > + qemu_free_net_client(nc->peer); > > + } else if (nc->peer) { > > + /* if there are RX packets pending, complete them */ > > + qemu_purge_queued_packets(nc->peer); > > } > > } > > > >
diff --git a/net/net.c b/net/net.c index 7a2a0fb5ac..a95b417300 100644 --- a/net/net.c +++ b/net/net.c @@ -411,10 +411,14 @@ void qemu_del_nic(NICState *nic) qemu_macaddr_set_free(&nic->conf->macaddr); - /* If this is a peer NIC and peer has already been deleted, free it now. */ - if (nic->peer_deleted) { - for (i = 0; i < queues; i++) { - qemu_free_net_client(qemu_get_subqueue(nic, i)->peer); + for (i = 0; i < queues; i++) { + NetClientState *nc = qemu_get_subqueue(nic, i); + /* If this is a peer NIC and peer has already been deleted, free it now. */ + if (nic->peer_deleted) { + qemu_free_net_client(nc->peer); + } else if (nc->peer) { + /* if there are RX packets pending, complete them */ + qemu_purge_queued_packets(nc->peer); } }
https://bugzilla.redhat.com/show_bug.cgi?id=1829272 When deleting queue pair, purge pending RX packets if any. Example of problematic flow: 1. Bring up q35 VM with tap (vhost off) and virtio-net or e1000e 2. Run ping flood to the VM NIC ( 1 ms interval) 3. Hot unplug the NIC device (device_del) During unplug process one or more packets come, the NIC can't receive, tap disables read_poll 4. Hot plug the device (device_add) with the same netdev The tap stays with read_poll disabled and does not receive any packets anymore (tap_send never triggered) Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com> --- net/net.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)