qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [Qemu-block] [PATCH 1/2] block: let blk_add/remove_aio_


From: Eric Blake
Subject: Re: [Qemu-devel] [Qemu-block] [PATCH 1/2] block: let blk_add/remove_aio_context_notifier() tolerate BDS changes
Date: Mon, 12 Mar 2018 07:26:07 -0500
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0

On 03/12/2018 06:27 AM, Stefan Hajnoczi wrote:
On Fri, Mar 09, 2018 at 09:56:44AM -0600, Eric Blake wrote:
On 03/06/2018 02:48 PM, Stefan Hajnoczi wrote:
Commit 2019ba0a0197 ("block: Add AioContextNotifier functions to BB")
added blk_add/remove_aio_context_notifier() and implemented them by
passing through the bdrv_*() equivalent.

This doesn't work across bdrv_append(), which detaches child->bs and
re-attaches it to a new BlockDriverState.  When
blk_remove_aio_context_notifier() is called we will access the new BDS
instead of the one where the notifier was added!

 From the point of view of the blk_*() API user, changes to the root BDS
should be transparent.

This patch maintains a list of AioContext notifiers in BlockBackend and
adds/removes them from the BlockDriverState as needed.


+typedef struct BlockBackendAioNotifier {
+    void (*attached_aio_context)(AioContext *new_context, void *opaque);
+    void (*detach_aio_context)(void *opaque);

Why the difference in tense (past 'attached' vs. present 'detach')?

The naming comes from the bdrv_add_aio_context_notifier() API:

   void bdrv_add_aio_context_notifier(BlockDriverState *bs,
         void (*attached_aio_context)(AioContext *new_context, void *opaque),
         void (*detach_aio_context)(void *opaque), void *opaque)

It's "attached" because bs->aio_context has already been assigned before
the callback is invoked.

It's "detach" because the callback is invoked before bs->aio_context is
cleared.

Not great naming and I found it weird when I looked at the code too, but
at least this patch keeps the BlockBackend naming consistent with the
BlockDriverState naming.

Odd, but consistent, so I can live with it.


+
+    QLIST_FOREACH(notifier, &blk->aio_notifiers, list) {
+        if (notifier->attached_aio_context == attached_aio_context &&
+            notifier->detach_aio_context == detach_aio_context &&
+            notifier->opaque == opaque) {
+            QLIST_REMOVE(notifier, list);

Don't you need to use QLIST_FOREACH_SAFE if you are going to modify the list
during traversal?

It doesn't matter since we return right away:

   g_free(notifier);
   return;

Okay, makes sense (a safe iteration is required if you keep iterating after action; but if you quit, the action has no impact on subsequent iteration since there is no further iteration).

Reviewed-by: Eric Blake <address@hidden>

--
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



reply via email to

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