From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
To: qemu-block@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>, Fam Zheng <fam@euphon.net>,
qemu-devel@nongnu.org,
Emanuele Giuseppe Esposito <eesposit@redhat.com>,
Markus Armbruster <armbru@redhat.com>,
Max Reitz <mreitz@redhat.com>,
Stefan Hajnoczi <stefanha@redhat.com>,
Paolo Bonzini <pbonzini@redhat.com>, John Snow <jsnow@redhat.com>
Subject: [PATCH v2 4/8] block: make before-write notifiers thread-safe
Date: Mon, 19 Apr 2021 10:55:37 +0200 [thread overview]
Message-ID: <20210419085541.22310-5-eesposit@redhat.com> (raw)
In-Reply-To: <20210419085541.22310-1-eesposit@redhat.com>
Reads access the list in RCU style, so be careful to avoid use-after-free
scenarios in the backup block job. Apart from this, all that's needed
is protecting updates with a mutex.
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
block.c | 6 +++---
block/io.c | 12 ++++++++++++
block/write-threshold.c | 2 +-
include/block/block_int.h | 37 +++++++++++++++++++++++++++++++++++++
4 files changed, 53 insertions(+), 4 deletions(-)
diff --git a/block.c b/block.c
index c5b887cec1..f40fb63c75 100644
--- a/block.c
+++ b/block.c
@@ -6434,7 +6434,7 @@ static void bdrv_do_remove_aio_context_notifier(BdrvAioNotifier *ban)
g_free(ban);
}
-static void bdrv_detach_aio_context(BlockDriverState *bs)
+void bdrv_detach_aio_context(BlockDriverState *bs)
{
BdrvAioNotifier *baf, *baf_tmp;
@@ -6462,8 +6462,8 @@ static void bdrv_detach_aio_context(BlockDriverState *bs)
bs->aio_context = NULL;
}
-static void bdrv_attach_aio_context(BlockDriverState *bs,
- AioContext *new_context)
+void bdrv_attach_aio_context(BlockDriverState *bs,
+ AioContext *new_context)
{
BdrvAioNotifier *ban, *ban_tmp;
diff --git a/block/io.c b/block/io.c
index ca2dca3007..8f6af6077b 100644
--- a/block/io.c
+++ b/block/io.c
@@ -3137,10 +3137,22 @@ bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov)
return true;
}
+static QemuSpin notifiers_spin_lock;
+
void bdrv_add_before_write_notifier(BlockDriverState *bs,
NotifierWithReturn *notifier)
{
+ qemu_spin_lock(¬ifiers_spin_lock);
notifier_with_return_list_add(&bs->before_write_notifiers, notifier);
+ qemu_spin_unlock(¬ifiers_spin_lock);
+}
+
+void bdrv_remove_before_write_notifier(BlockDriverState *bs,
+ NotifierWithReturn *notifier)
+{
+ qemu_spin_lock(¬ifiers_spin_lock);
+ notifier_with_return_remove(notifier);
+ qemu_spin_unlock(¬ifiers_spin_lock);
}
void bdrv_io_plug(BlockDriverState *bs)
diff --git a/block/write-threshold.c b/block/write-threshold.c
index 77c74bdaa7..b87b749b02 100644
--- a/block/write-threshold.c
+++ b/block/write-threshold.c
@@ -32,7 +32,7 @@ bool bdrv_write_threshold_is_set(const BlockDriverState *bs)
static void write_threshold_disable(BlockDriverState *bs)
{
if (bdrv_write_threshold_is_set(bs)) {
- notifier_with_return_remove(&bs->write_threshold_notifier);
+ bdrv_remove_before_write_notifier(bs, &bs->write_threshold_notifier);
bs->write_threshold_offset = 0;
}
}
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 88e4111939..a1aad5ad2d 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -1089,6 +1089,8 @@ bool bdrv_backing_overridden(BlockDriverState *bs);
/**
* bdrv_add_before_write_notifier:
+ * @bs: The #BlockDriverState for which to register the notifier
+ * @notifier: The notifier to add
*
* Register a callback that is invoked before write requests are processed but
* after any throttling or waiting for overlapping requests.
@@ -1096,6 +1098,41 @@ bool bdrv_backing_overridden(BlockDriverState *bs);
void bdrv_add_before_write_notifier(BlockDriverState *bs,
NotifierWithReturn *notifier);
+/**
+ * bdrv_remove_before_write_notifier:
+ * @bs: The #BlockDriverState for which to register the notifier
+ * @notifier: The notifier to add
+ *
+ * Unregister a callback that is invoked before write requests are processed but
+ * after any throttling or waiting for overlapping requests.
+ *
+ * Note that more I/O could be pending on @bs. You need to wait for
+ * it to finish, for example with bdrv_drain(), before freeing @notifier.
+ */
+void bdrv_remove_before_write_notifier(BlockDriverState *bs,
+ NotifierWithReturn *notifier);
+
+/**
+ * bdrv_detach_aio_context:
+ *
+ * May be called from .bdrv_detach_aio_context() to detach children from the
+ * current #AioContext. This is only needed by block drivers that manage their
+ * own children. Both ->file and ->backing are automatically handled and
+ * block drivers should not call this function on them explicitly.
+ */
+void bdrv_detach_aio_context(BlockDriverState *bs);
+
+/**
+ * bdrv_attach_aio_context:
+ *
+ * May be called from .bdrv_attach_aio_context() to attach children to the new
+ * #AioContext. This is only needed by block drivers that manage their own
+ * children. Both ->file and ->backing are automatically handled and block
+ * drivers should not call this function on them explicitly.
+ */
+void bdrv_attach_aio_context(BlockDriverState *bs,
+ AioContext *new_context);
+
/**
* bdrv_add_aio_context_notifier:
*
--
2.30.2
next prev parent reply other threads:[~2021-04-19 9:02 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-04-19 8:55 [PATCH v2 0/8] Block layer thread-safety, continued Emanuele Giuseppe Esposito
2021-04-19 8:55 ` [PATCH v2 1/8] block: prepare write threshold code for thread safety Emanuele Giuseppe Esposito
2021-05-05 8:50 ` Stefan Hajnoczi
2021-05-05 9:54 ` Vladimir Sementsov-Ogievskiy
2021-05-06 9:04 ` Stefan Hajnoczi
2021-05-06 9:14 ` Vladimir Sementsov-Ogievskiy
2021-04-19 8:55 ` [PATCH v2 2/8] block: protect write threshold QMP commands from concurrent requests Emanuele Giuseppe Esposito
2021-05-05 8:55 ` Stefan Hajnoczi
2021-05-05 11:29 ` Paolo Bonzini
2021-04-19 8:55 ` [PATCH v2 3/8] util: use RCU accessors for notifiers Emanuele Giuseppe Esposito
2021-05-05 9:47 ` Stefan Hajnoczi
2021-04-19 8:55 ` Emanuele Giuseppe Esposito [this message]
2021-04-21 21:23 ` [PATCH v2 4/8] block: make before-write notifiers thread-safe Vladimir Sementsov-Ogievskiy
2021-04-21 22:17 ` Vladimir Sementsov-Ogievskiy
2021-04-19 8:55 ` [PATCH v2 5/8] block: add a few more notes on locking Emanuele Giuseppe Esposito
2021-05-05 9:53 ` Stefan Hajnoczi
2021-04-19 8:55 ` [PATCH v2 6/8] block: do not acquire AioContext in check_to_replace_node Emanuele Giuseppe Esposito
2021-05-05 10:10 ` Paolo Bonzini
2021-04-19 8:55 ` [PATCH v2 7/8] block/replication: do not acquire AioContext Emanuele Giuseppe Esposito
2021-05-05 9:57 ` Stefan Hajnoczi
2021-05-05 10:33 ` Paolo Bonzini
2021-04-19 8:55 ` [PATCH v2 8/8] block: do not take AioContext around reopen Emanuele Giuseppe Esposito
2021-04-21 12:24 ` Paolo Bonzini
2021-05-05 10:01 ` Stefan Hajnoczi
2021-04-21 12:25 ` [PATCH v2 0/8] Block layer thread-safety, continued Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210419085541.22310-5-eesposit@redhat.com \
--to=eesposit@redhat.com \
--cc=armbru@redhat.com \
--cc=fam@euphon.net \
--cc=jsnow@redhat.com \
--cc=kwolf@redhat.com \
--cc=mreitz@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).