mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-05 16:53:55 -06:00
![]() During the hot-unplugging of vhost-user-net type network cards,
the vhost_user_cleanup function may add the same rcu node to
the rcu linked list. The function call in this case is as follows:
vhost_user_cleanup
->vhost_user_host_notifier_remove
->call_rcu(n, vhost_user_host_notifier_free, rcu);
->g_free_rcu(n, rcu);
When this happens, QEMU will abort in try_dequeue:
if (head == &dummy && qatomic_mb_read(&tail) == &dummy.next) {
abort();
}
backtrace is as follows:
0 __pthread_kill_implementation () at /usr/lib64/libc.so.6
1 raise () at /usr/lib64/libc.so.6
2 abort () at /usr/lib64/libc.so.6
3 try_dequeue () at ../util/rcu.c:235
4 call_rcu_thread (0) at ../util/rcu.c:288
5 qemu_thread_start (0) at ../util/qemu-thread-posix.c:541
6 start_thread () at /usr/lib64/libc.so.6
7 clone3 () at /usr/lib64/libc.so.6
The reason for the abort is that adding two identical nodes to
the rcu linked list will cause the rcu linked list to become a ring,
but when the dummy node is added after the two identical nodes,
the ring is opened. But only one node is added to list with
rcu_call_count added twice. This will cause rcu try_dequeue abort.
This happens when n->addr != 0. In some scenarios, this does happen.
For example, this situation will occur when using a 32-queue DPU
vhost-user-net type network card for hot-unplug testing, because
VhostUserHostNotifier->addr will be cleared during the processing of
VHOST_USER_BACKEND_VRING_HOST_NOTIFIER_MSG. However,it is asynchronous,
so we cannot guarantee that VhostUserHostNotifier->addr is zero in
vhost_user_cleanup. Therefore, it is necessary to merge g_free_rcu
and vhost_user_host_notifier_free into one rcu node.
Fixes:
|
||
---|---|---|
.. | ||
vdpa-dev.h | ||
vhost-backend.h | ||
vhost-scsi-common.h | ||
vhost-scsi.h | ||
vhost-user-base.h | ||
vhost-user-blk.h | ||
vhost-user-fs.h | ||
vhost-user-gpio.h | ||
vhost-user-i2c.h | ||
vhost-user-rng.h | ||
vhost-user-scmi.h | ||
vhost-user-scsi.h | ||
vhost-user-snd.h | ||
vhost-user-vsock.h | ||
vhost-user.h | ||
vhost-vdpa.h | ||
vhost-vsock-common.h | ||
vhost-vsock.h | ||
vhost.h | ||
virtio-access.h | ||
virtio-acpi.h | ||
virtio-balloon.h | ||
virtio-blk-common.h | ||
virtio-blk.h | ||
virtio-bus.h | ||
virtio-crypto.h | ||
virtio-dmabuf.h | ||
virtio-gpu-bswap.h | ||
virtio-gpu-pci.h | ||
virtio-gpu-pixman.h | ||
virtio-gpu.h | ||
virtio-input.h | ||
virtio-iommu.h | ||
virtio-md-pci.h | ||
virtio-mem.h | ||
virtio-mmio.h | ||
virtio-net.h | ||
virtio-pci.h | ||
virtio-pmem.h | ||
virtio-rng.h | ||
virtio-scsi.h | ||
virtio-serial.h | ||
virtio.h |