David Hildenbrand
2021-Aug-25 10:24 UTC
[PATCH v1] virtio-mem: fix sleeping in RCU read side section in virtio_mem_online_page_cb()
virtio_mem_set_fake_offline() might sleep now, and we call it under rcu_read_lock(). To fix it, simply move the rcu_read_unlock() further up, as we're done with the device. Reported-by: Dan Carpenter <dan.carpenter at oracle.com> Fixes: 6cc26d77613a: "virtio-mem: use page_offline_(start|end) when setting PageOffline() Cc: "Michael S. Tsirkin" <mst at redhat.com> Cc: Jason Wang <jasowang at redhat.com> Cc: Andrew Morton <akpm at linux-foundation.org> Cc: Linus Torvalds <torvalds at linux-foundation.org> Cc: virtualization at lists.linux-foundation.org Signed-off-by: David Hildenbrand <david at redhat.com> --- The problematic commit is in v5.14-rc1 .. v5.14-rc7, but it suspect might be too late for v5.14. The original commit went upstream via Andrews tree, we could take this fix via Andrews tree as well or via the vhost tree (MST), I don't particularly care. (putting Linus on CC just in case) --- drivers/virtio/virtio_mem.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/virtio/virtio_mem.c b/drivers/virtio/virtio_mem.c index 09ed55de07d7..b91bc810a87e 100644 --- a/drivers/virtio/virtio_mem.c +++ b/drivers/virtio/virtio_mem.c @@ -1242,12 +1242,19 @@ static void virtio_mem_online_page_cb(struct page *page, unsigned int order) do_online = virtio_mem_bbm_get_bb_state(vm, id) ! VIRTIO_MEM_BBM_BB_FAKE_OFFLINE; } + + /* + * virtio_mem_set_fake_offline() might sleep, we don't need + * the device anymore. See virtio_mem_remove() how races + * between memory onlining and device removal are handled. + */ + rcu_read_unlock(); + if (do_online) generic_online_page(page, order); else virtio_mem_set_fake_offline(PFN_DOWN(addr), 1 << order, false); - rcu_read_unlock(); return; } rcu_read_unlock(); -- 2.31.1