From 425bec0032f59eeee12520085cd054fac09cc66e Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Wed, 25 Aug 2021 12:24:15 +0200 Subject: [PATCH] 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 Fixes: 6cc26d77613a: "virtio-mem: use page_offline_(start|end) when setting PageOffline() Cc: "Michael S. Tsirkin" Cc: Jason Wang Cc: Andrew Morton Cc: virtualization@lists.linux-foundation.org Signed-off-by: David Hildenbrand Signed-off-by: Linus Torvalds --- 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 09ed55d..b91bc81 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.7.4