[PATCH] block/io: skip conflict scan when no serialising requests exist

Bin Guo posted 1 patch 1 day, 13 hours ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260529031215.59494-1-guobin@linux.alibaba.com
Maintainers: Stefan Hajnoczi <stefanha@redhat.com>, Fam Zheng <fam@euphon.net>, Kevin Wolf <kwolf@redhat.com>, Hanna Reitz <hreitz@redhat.com>
block/io.c | 9 +++++++++
1 file changed, 9 insertions(+)
[PATCH] block/io: skip conflict scan when no serialising requests exist
Posted by Bin Guo 1 day, 13 hours ago
bdrv_find_conflicting_request() always linearly scans the
tracked_requests list looking for overlapping serialising requests.
However, BlockDriverState already maintains a serialising_in_flight
atomic counter that is incremented/decremented as serialising
requests are created/destroyed.

When the counter is zero there are no serialising requests in the
list and the scan is guaranteed to find nothing, so return NULL
immediately.  This complements the existing fast path in
bdrv_wait_serialising_requests() which checks the same counter
before acquiring reqs_lock.

No functional change.

Signed-off-by: Bin Guo <guobin@linux.alibaba.com>
---
 block/io.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/block/io.c b/block/io.c
index e8fb4ede4d..eb7ba59a90 100644
--- a/block/io.c
+++ b/block/io.c
@@ -649,6 +649,15 @@ bdrv_find_conflicting_request(BdrvTrackedRequest *self)
 {
     BdrvTrackedRequest *req;
 
+    /*
+     * Fast path: if there are no serialising requests in flight, there
+     * can be no conflicts.  This mirrors the check in
+     * bdrv_wait_serialising_requests().
+     */
+    if (!qatomic_read(&self->bs->serialising_in_flight)) {
+        return NULL;
+    }
+
     QLIST_FOREACH(req, &self->bs->tracked_requests, list) {
         if (req == self || (!req->serialising && !self->serialising)) {
             continue;
-- 
2.50.1 (Apple Git-155)
Re: [PATCH] block/io: skip conflict scan when no serialising requests exist
Posted by Kevin Wolf 1 day, 2 hours ago
Am 29.05.2026 um 05:12 hat Bin Guo geschrieben:
> bdrv_find_conflicting_request() always linearly scans the
> tracked_requests list looking for overlapping serialising requests.
> However, BlockDriverState already maintains a serialising_in_flight
> atomic counter that is incremented/decremented as serialising
> requests are created/destroyed.
> 
> When the counter is zero there are no serialising requests in the
> list and the scan is guaranteed to find nothing, so return NULL
> immediately.  This complements the existing fast path in
> bdrv_wait_serialising_requests() which checks the same counter
> before acquiring reqs_lock.
> 
> No functional change.
> 
> Signed-off-by: Bin Guo <guobin@linux.alibaba.com>
> ---
>  block/io.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/block/io.c b/block/io.c
> index e8fb4ede4d..eb7ba59a90 100644
> --- a/block/io.c
> +++ b/block/io.c
> @@ -649,6 +649,15 @@ bdrv_find_conflicting_request(BdrvTrackedRequest *self)
>  {
>      BdrvTrackedRequest *req;
>  
> +    /*
> +     * Fast path: if there are no serialising requests in flight, there
> +     * can be no conflicts.  This mirrors the check in
> +     * bdrv_wait_serialising_requests().
> +     */
> +    if (!qatomic_read(&self->bs->serialising_in_flight)) {
> +        return NULL;
> +    }

Isn't this dead code? You get the following callers:

- bdrv_wait_serialising_requests_locked
  - bdrv_wait_serialising_requests: Already has the check, as you
    mention in the commit message
  - bdrv_make_request_serialising: tracked_request_set_serialising()
    increases bs->serialising_in_flight
- bdrv_co_write_req_prepare: tracked_request_set_serialising() again

I think the only way this could trigger if you hit the minimal race
window in bdrv_wait_serialising_requests() between the identical check
and taking the lock.

Kevin