qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 3/3] block-ram-registrar: reset when the graph changes


From: Stefan Hajnoczi
Subject: [PATCH 3/3] block-ram-registrar: reset when the graph changes
Date: Wed, 4 Jan 2023 17:06:31 -0500

The BDRV_REQ_REGISTERED_BUF flag can be set on I/O requests to indicate
that I/O buffers were previously registered using bdrv_register_buf().
block-ram-registrar automatically registers guest RAM so that emulated
storage controllers can set BDRV_REQ_REGISTERED_BUF without having to
worry about registering buffers themselves.

Kevin Wolf <kwolf@redhat.com> pointed out that block-ram-registrar does
not handle graph changes. This means buffers aren't unregistered when a
node is removed from the graph and buffer registrations aren't replayed
when a new node is inserted in the graph. Therefore
BDRV_REQ_REGISTERED_BUF may be set but the buffer wasn't previously
registered with the new node.

Fix this by monitoring graph changes and replaying buffer registration.
Note that the ram_block_notifier_add() API enumerates all RAM blocks so
we don't need to manually replay them.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 block/block-ram-registrar.c | 40 ++++++++++++++++++++++++++++++++-----
 1 file changed, 35 insertions(+), 5 deletions(-)

diff --git a/block/block-ram-registrar.c b/block/block-ram-registrar.c
index 25dbafa789..1a111ac124 100644
--- a/block/block-ram-registrar.c
+++ b/block/block-ram-registrar.c
@@ -33,6 +33,35 @@ static void ram_block_removed(RAMBlockNotifier *n, void 
*host, size_t size,
     blk_unregister_buf(r->blk, host, max_size);
 }
 
+static void remove_ram_block_notifier(BlockRAMRegistrar *r)
+{
+    if (r->ok) {
+        ram_block_notifier_remove(&r->notifier);
+    }
+}
+
+static void add_ram_block_notifier(BlockRAMRegistrar *r)
+{
+    r->ok = true; /* reset flag in case it was false */
+    ram_block_notifier_add(&r->notifier);
+}
+
+static void graph_change_pre_detach(BlockBackend *blk, void *opaque)
+{
+    BlockRAMRegistrar *r = opaque;
+
+    /* Unregisters all buffers from all BDSes */
+    remove_ram_block_notifier(r);
+}
+
+static void graph_change_post_attach(BlockBackend *blk, void *opaque)
+{
+    BlockRAMRegistrar *r = opaque;
+
+    /* Re-registers all buffers with all BDSes */
+    add_ram_block_notifier(r);
+}
+
 void blk_ram_registrar_init(BlockRAMRegistrar *r, BlockBackend *blk)
 {
     r->blk = blk;
@@ -45,14 +74,15 @@ void blk_ram_registrar_init(BlockRAMRegistrar *r, 
BlockBackend *blk)
          * value that does not change across resize.
          */
     };
-    r->ok = true;
 
-    ram_block_notifier_add(&r->notifier);
+    blk_add_graph_change_notifier(blk, graph_change_pre_detach,
+                                  graph_change_post_attach, r);
+    add_ram_block_notifier(r);
 }
 
 void blk_ram_registrar_destroy(BlockRAMRegistrar *r)
 {
-    if (r->ok) {
-        ram_block_notifier_remove(&r->notifier);
-    }
+    remove_ram_block_notifier(r);
+    blk_remove_graph_change_notifier(r->blk, graph_change_pre_detach,
+                                     graph_change_post_attach, r);
 }
-- 
2.39.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]