From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
To: qemu-block@nongnu.org
Cc: fam@euphon.net, kwolf@redhat.com, vsementsov@virtuozzo.com,
Anton.Nefedov@acronis.com, armbru@redhat.com,
qemu-devel@nongnu.org, mreitz@redhat.com, stefanha@redhat.com,
den@openvz.org
Subject: [PATCH 1/5] block/io: introduce bdrv_try_mark_request_serialising
Date: Sat, 20 Jun 2020 17:36:45 +0300 [thread overview]
Message-ID: <20200620143649.225852-2-vsementsov@virtuozzo.com> (raw)
In-Reply-To: <20200620143649.225852-1-vsementsov@virtuozzo.com>
Introduce a function to mark the request serialising only if there are
no conflicting request to wait for.
The function is static, so mark it unused. The attribute is to be
dropped in the next commit.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
---
block/io.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 51 insertions(+), 7 deletions(-)
diff --git a/block/io.c b/block/io.c
index df8f2a98d4..60cee1d759 100644
--- a/block/io.c
+++ b/block/io.c
@@ -727,10 +727,11 @@ static bool tracked_request_overlaps(BdrvTrackedRequest *req,
return true;
}
-static bool coroutine_fn
-bdrv_wait_serialising_requests_locked(BlockDriverState *bs,
- BdrvTrackedRequest *self)
+/* Called with self->bs->reqs_lock locked */
+static bool coroutine_fn wait_or_find_conflicts(BdrvTrackedRequest *self,
+ bool wait)
{
+ BlockDriverState *bs = self->bs;
BdrvTrackedRequest *req;
bool retry;
bool waited = false;
@@ -754,6 +755,9 @@ bdrv_wait_serialising_requests_locked(BlockDriverState *bs,
* will wait for us as soon as it wakes up, then just go on
* (instead of producing a deadlock in the former case). */
if (!req->waiting_for) {
+ if (!wait) {
+ return true;
+ }
self->waiting_for = req;
qemu_co_queue_wait(&req->wait_queue, &bs->reqs_lock);
self->waiting_for = NULL;
@@ -767,13 +771,18 @@ bdrv_wait_serialising_requests_locked(BlockDriverState *bs,
return waited;
}
-bool bdrv_mark_request_serialising(BdrvTrackedRequest *req, uint64_t align)
+/* Return true on success, false on fail. Always success with blocking = true */
+static bool bdrv_do_mark_request_serialising(BdrvTrackedRequest *req,
+ uint64_t align, bool blocking, bool *waited)
{
BlockDriverState *bs = req->bs;
int64_t overlap_offset = req->offset & ~(align - 1);
uint64_t overlap_bytes = ROUND_UP(req->offset + req->bytes, align)
- overlap_offset;
- bool waited;
+ int64_t old_overlap_offset = req->overlap_offset;
+ uint64_t old_overlap_bytes = req->overlap_bytes;
+ bool old_serializing = req->serialising;
+ bool found;
qemu_co_mutex_lock(&bs->reqs_lock);
if (!req->serialising) {
@@ -783,11 +792,46 @@ bool bdrv_mark_request_serialising(BdrvTrackedRequest *req, uint64_t align)
req->overlap_offset = MIN(req->overlap_offset, overlap_offset);
req->overlap_bytes = MAX(req->overlap_bytes, overlap_bytes);
- waited = bdrv_wait_serialising_requests_locked(bs, req);
+ found = wait_or_find_conflicts(req, blocking);
+
+ if (!blocking && found) {
+ req->overlap_offset = old_overlap_offset;
+ req->overlap_bytes = old_overlap_bytes;
+ if (!old_serializing) {
+ atomic_dec(&req->bs->serialising_in_flight);
+ req->serialising = false;
+ }
+ }
+
+ *waited = found && blocking;
+
qemu_co_mutex_unlock(&bs->reqs_lock);
+
+ return blocking || !found;
+}
+
+/* Return true if had to wait for conflicts */
+bool bdrv_mark_request_serialising(BdrvTrackedRequest *req, uint64_t align)
+{
+ bool waited;
+ bool success = bdrv_do_mark_request_serialising(req, align, true, &waited);
+
+ assert(success);
return waited;
}
+/* Return true on success, false if there are some conflicts */
+__attribute__ ((unused))
+static bool bdrv_try_mark_request_serialising(BdrvTrackedRequest *req,
+ uint64_t align)
+{
+ bool waited;
+ bool success = bdrv_do_mark_request_serialising(req, align, false, &waited);
+
+ assert(!waited);
+ return success;
+}
+
/**
* Return the tracked request on @bs for the current coroutine, or
* NULL if there is none.
@@ -865,7 +909,7 @@ static bool coroutine_fn bdrv_wait_serialising_requests(BdrvTrackedRequest *self
}
qemu_co_mutex_lock(&bs->reqs_lock);
- waited = bdrv_wait_serialising_requests_locked(bs, self);
+ waited = wait_or_find_conflicts(self, true);
qemu_co_mutex_unlock(&bs->reqs_lock);
return waited;
--
2.18.0
next prev parent reply other threads:[~2020-06-20 14:38 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-06-20 14:36 [PATCH 0/5] preallocate filter Vladimir Sementsov-Ogievskiy
2020-06-20 14:36 ` Vladimir Sementsov-Ogievskiy [this message]
2020-07-07 15:56 ` [PATCH 1/5] block/io: introduce bdrv_try_mark_request_serialising Stefan Hajnoczi
2020-07-08 15:51 ` Vladimir Sementsov-Ogievskiy
2020-07-13 11:23 ` Stefan Hajnoczi
2020-06-20 14:36 ` [PATCH 2/5] block/io: introduce bdrv_co_range_try_lock Vladimir Sementsov-Ogievskiy
2020-07-07 16:10 ` Stefan Hajnoczi
2020-07-08 15:56 ` Vladimir Sementsov-Ogievskiy
2020-07-13 11:23 ` Stefan Hajnoczi
2020-06-20 14:36 ` [PATCH 3/5] block: introduce preallocate filter Vladimir Sementsov-Ogievskiy
2020-07-08 12:07 ` Stefan Hajnoczi
2020-07-08 16:17 ` Vladimir Sementsov-Ogievskiy
2020-07-13 11:27 ` Stefan Hajnoczi
2020-06-20 14:36 ` [PATCH 4/5] iotests: QemuIoInteractive: use qemu_io_args_no_fmt Vladimir Sementsov-Ogievskiy
2020-07-08 12:08 ` Stefan Hajnoczi
2020-06-20 14:36 ` [PATCH 5/5] iotests: add 298 to test new preallocate filter driver Vladimir Sementsov-Ogievskiy
2020-07-08 12:09 ` Stefan Hajnoczi
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=20200620143649.225852-2-vsementsov@virtuozzo.com \
--to=vsementsov@virtuozzo.com \
--cc=Anton.Nefedov@acronis.com \
--cc=armbru@redhat.com \
--cc=den@openvz.org \
--cc=fam@euphon.net \
--cc=kwolf@redhat.com \
--cc=mreitz@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).