All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
To: qemu-block@nongnu.org
Cc: qemu-devel@nongnu.org, vsementsov@virtuozzo.com,
	hreitz@redhat.com, kwolf@redhat.com
Subject: [PATCH v7 10/11] block/reqlist: implement reqlist_mark_req_invalid()
Date: Sat,  4 Sep 2021 19:24:27 +0300	[thread overview]
Message-ID: <20210904162428.222008-11-vsementsov@virtuozzo.com> (raw)
In-Reply-To: <20210904162428.222008-1-vsementsov@virtuozzo.com>

We do lock qcow2 s->lock only to remove request from the reqlist.
That's quite inefficient. Let's implement atomic operation to avoid
extra critical section.

So new interface is:

1. Instead of reqlist_free_req() user may call atomic
   reqlist_mark_req_invalid().

2. At some moment under mutex user calls reqlist_free_invalid_reqs() to
   free RAM.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
---
 include/block/reqlist.h | 13 +++++++++++++
 block/reqlist.c         | 23 ++++++++++++++++++++++-
 2 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/include/block/reqlist.h b/include/block/reqlist.h
index 32dc87666f..24d6d93a6e 100644
--- a/include/block/reqlist.h
+++ b/include/block/reqlist.h
@@ -26,6 +26,7 @@
 typedef struct BlockReq {
     int64_t offset;
     int64_t bytes;
+    bool valid;
 
     CoQueue wait_queue; /* coroutines blocked on this req */
     QLIST_ENTRY(BlockReq) list;
@@ -84,4 +85,16 @@ static inline void reqlist_free_req(BlockReq *req)
     }
 }
 
+/*
+ * Invalid request will be ignored when searching for conflicts.
+ * The function modifies .valid atomically and intended for use when we
+ * want to avoid using mutex.
+ * If you use this function don't forget to also call
+ * reqlist_free_invalid_reqs() sometimes, so that list doesn't grow endlessly.
+ */
+void reqlist_mark_req_invalid(BlockReq *req);
+
+/* Remove all invalid requests to free RAM space */
+void reqlist_free_invalid_reqs(BlockReqList *reqs);
+
 #endif /* REQLIST_H */
diff --git a/block/reqlist.c b/block/reqlist.c
index c580752db7..641307d80d 100644
--- a/block/reqlist.c
+++ b/block/reqlist.c
@@ -14,6 +14,8 @@
 
 #include "qemu/osdep.h"
 
+#include "qemu/atomic.h"
+
 #include "block/reqlist.h"
 
 void reqlist_init_req(BlockReqList *reqs, BlockReq *req, int64_t offset,
@@ -22,6 +24,7 @@ void reqlist_init_req(BlockReqList *reqs, BlockReq *req, int64_t offset,
     *req = (BlockReq) {
         .offset = offset,
         .bytes = bytes,
+        .valid = true,
     };
     qemu_co_queue_init(&req->wait_queue);
     QLIST_INSERT_HEAD(reqs, req, list);
@@ -33,7 +36,9 @@ BlockReq *reqlist_find_conflict(BlockReqList *reqs, int64_t offset,
     BlockReq *r;
 
     QLIST_FOREACH(r, reqs, list) {
-        if (offset + bytes > r->offset && offset < r->offset + r->bytes) {
+        if (r->valid &&
+            offset + bytes > r->offset && offset < r->offset + r->bytes)
+        {
             return r;
         }
     }
@@ -72,3 +77,19 @@ void coroutine_fn reqlist_remove_req(BlockReq *req)
     QLIST_REMOVE(req, list);
     qemu_co_queue_restart_all(&req->wait_queue);
 }
+
+void reqlist_mark_req_invalid(BlockReq *req)
+{
+    qatomic_set(&req->valid, false);
+}
+
+void reqlist_free_invalid_reqs(BlockReqList *reqs)
+{
+    BlockReq *r, *next;
+
+    QLIST_FOREACH_SAFE(r, reqs, list, next) {
+        if (!r->valid) {
+            reqlist_free_req(r);
+        }
+    }
+}
-- 
2.29.2



  parent reply	other threads:[~2021-09-04 16:38 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-04 16:24 [PATCH v7 00/11] qcow2: fix parallel rewrite and discard (reqlist) Vladimir Sementsov-Ogievskiy
2021-09-04 16:24 ` [PATCH v7 01/11] block/reqlist: drop extra assertion Vladimir Sementsov-Ogievskiy
2021-09-04 16:24 ` [PATCH v7 02/11] block/reqlist: add reqlist_new_req() and reqlist_free_req() Vladimir Sementsov-Ogievskiy
2021-09-04 16:24 ` [PATCH v7 03/11] iotests: add qcow2-discard-during-rewrite Vladimir Sementsov-Ogievskiy
2021-09-04 16:24 ` [PATCH v7 04/11] qcow2: introduce qcow2_parse_compressed_cluster_descriptor() Vladimir Sementsov-Ogievskiy
2021-09-04 16:24 ` [PATCH v7 05/11] qcow2: refactor qcow2_co_preadv_task() to have one return Vladimir Sementsov-Ogievskiy
2021-09-04 16:24 ` [PATCH v7 06/11] qcow2: prepare for tracking guest io requests in data_file Vladimir Sementsov-Ogievskiy
2021-09-04 16:24 ` [PATCH v7 07/11] qcow2: track " Vladimir Sementsov-Ogievskiy
2021-09-04 16:24 ` [PATCH v7 08/11] qcow2: introduce is_cluster_free() helper Vladimir Sementsov-Ogievskiy
2021-09-04 16:24 ` [PATCH v7 09/11] qcow2: don't reallocate host clusters under guest operation Vladimir Sementsov-Ogievskiy
2021-09-04 16:24 ` Vladimir Sementsov-Ogievskiy [this message]
2021-09-04 16:24 ` [PATCH v7 11/11] qcow2: use reqlist_mark_req_invalid() Vladimir Sementsov-Ogievskiy
2021-09-22  8:24 ` [PATCH v7 00/11] qcow2: fix parallel rewrite and discard (reqlist) Vladimir Sementsov-Ogievskiy

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=20210904162428.222008-11-vsementsov@virtuozzo.com \
    --to=vsementsov@virtuozzo.com \
    --cc=hreitz@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.