diff options
author | David Hildenbrand <david@redhat.com> | 2021-08-25 12:24:15 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-08-27 11:39:36 -0700 |
commit | 425bec0032f59eeee12520085cd054fac09cc66e (patch) | |
tree | 25477a10d8312d0c89b9ab2779c4821c8c7d56b5 | |
parent | 5a61b7a29647ed7c939ca76d3bf83c75d10ba16e (diff) | |
download | linux-425bec0032f59eeee12520085cd054fac09cc66e.tar.bz2 |
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@oracle.com>
Fixes: 6cc26d77613a: "virtio-mem: use page_offline_(start|end) when setting PageOffline()
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Jason Wang <jasowang@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: virtualization@lists.linux-foundation.org
Signed-off-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/virtio/virtio_mem.c | 9 |
1 files changed, 8 insertions, 1 deletions
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(); |