net/net.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
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(-)
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);
}
}
--
2.17.1
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); > > } > > } > > > >
© 2016 - 2024 Red Hat, Inc.