All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stefan Hajnoczi <stefanha@redhat.com>
To: qemu-devel@nongnu.org
Cc: "Kevin Wolf" <kwolf@redhat.com>,
	"Peter Maydell" <peter.maydell@linaro.org>,
	"Thomas Huth" <thuth@redhat.com>,
	"Eduardo Habkost" <ehabkost@redhat.com>,
	qemu-block@nongnu.org, "Michael S. Tsirkin" <mst@redhat.com>,
	"Laurent Vivier" <lvivier@redhat.com>,
	"Max Reitz" <mreitz@redhat.com>,
	"Alexander Bulekov" <alxndr@bu.edu>,
	"Bandan Das" <bsd@redhat.com>,
	"Stefan Hajnoczi" <stefanha@redhat.com>,
	"Marc-André Lureau" <marcandre.lureau@redhat.com>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Fam Zheng" <fam@euphon.net>,
	"Richard Henderson" <rth@twiddle.net>
Subject: [PULL 03/31] rcu_queue: add QSLIST functions
Date: Sat, 22 Feb 2020 08:50:02 +0000	[thread overview]
Message-ID: <20200222085030.1760640-4-stefanha@redhat.com> (raw)
In-Reply-To: <20200222085030.1760640-1-stefanha@redhat.com>

From: Paolo Bonzini <pbonzini@redhat.com>

QSLIST is the only family of lists for which we do not have RCU-friendly accessors,
add them.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 20200220103828.24525-1-pbonzini@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 include/qemu/queue.h     | 15 +++++++++++--
 include/qemu/rcu_queue.h | 47 ++++++++++++++++++++++++++++++++++++++++
 tests/Makefile.include   |  2 ++
 tests/test-rcu-list.c    | 16 ++++++++++++++
 tests/test-rcu-slist.c   |  2 ++
 5 files changed, 80 insertions(+), 2 deletions(-)
 create mode 100644 tests/test-rcu-slist.c

diff --git a/include/qemu/queue.h b/include/qemu/queue.h
index 19425f973f..fcecb70228 100644
--- a/include/qemu/queue.h
+++ b/include/qemu/queue.h
@@ -211,9 +211,20 @@ struct {                                                                \
         (head)->slh_first = (head)->slh_first->field.sle_next;          \
 } while (/*CONSTCOND*/0)
 
-#define QSLIST_REMOVE_AFTER(slistelm, field) do {                        \
+#define QSLIST_REMOVE_AFTER(slistelm, field) do {                       \
         (slistelm)->field.sle_next =                                    \
-            QSLIST_NEXT(QSLIST_NEXT((slistelm), field), field);           \
+            QSLIST_NEXT(QSLIST_NEXT((slistelm), field), field);         \
+} while (/*CONSTCOND*/0)
+
+#define QSLIST_REMOVE(head, elm, type, field) do {                      \
+    if ((head)->slh_first == (elm)) {                                   \
+        QSLIST_REMOVE_HEAD((head), field);                              \
+    } else {                                                            \
+        struct type *curelm = (head)->slh_first;                        \
+        while (curelm->field.sle_next != (elm))                         \
+            curelm = curelm->field.sle_next;                            \
+        curelm->field.sle_next = curelm->field.sle_next->field.sle_next; \
+    }                                                                   \
 } while (/*CONSTCOND*/0)
 
 #define QSLIST_FOREACH(var, head, field)                                 \
diff --git a/include/qemu/rcu_queue.h b/include/qemu/rcu_queue.h
index 2d386f303e..558961cc27 100644
--- a/include/qemu/rcu_queue.h
+++ b/include/qemu/rcu_queue.h
@@ -262,6 +262,53 @@ extern "C" {
          (var) && ((next) = atomic_rcu_read(&(var)->field.tqe_next), 1); \
          (var) = (next))
 
+/*
+ * RCU singly-linked list
+ */
+
+/* Singly-linked list access methods */
+#define QSLIST_EMPTY_RCU(head)      (atomic_read(&(head)->slh_first) == NULL)
+#define QSLIST_FIRST_RCU(head)       atomic_rcu_read(&(head)->slh_first)
+#define QSLIST_NEXT_RCU(elm, field)  atomic_rcu_read(&(elm)->field.sle_next)
+
+/* Singly-linked list functions */
+#define QSLIST_INSERT_HEAD_RCU(head, elm, field) do {           \
+    (elm)->field.sle_next = (head)->slh_first;                  \
+    atomic_rcu_set(&(head)->slh_first, (elm));                  \
+} while (/*CONSTCOND*/0)
+
+#define QSLIST_INSERT_AFTER_RCU(head, listelm, elm, field) do {         \
+    (elm)->field.sle_next = (listelm)->field.sle_next;                  \
+    atomic_rcu_set(&(listelm)->field.sle_next, (elm));                  \
+} while (/*CONSTCOND*/0)
+
+#define QSLIST_REMOVE_HEAD_RCU(head, field) do {                       \
+    atomic_set(&(head)->slh_first, (head)->slh_first->field.sle_next); \
+} while (/*CONSTCOND*/0)
+
+#define QSLIST_REMOVE_RCU(head, elm, type, field) do {              \
+    if ((head)->slh_first == (elm)) {                               \
+        QSLIST_REMOVE_HEAD_RCU((head), field);                      \
+    } else {                                                        \
+        struct type *curr = (head)->slh_first;                      \
+        while (curr->field.sle_next != (elm)) {                     \
+            curr = curr->field.sle_next;                            \
+        }                                                           \
+        atomic_set(&curr->field.sle_next,                           \
+                   curr->field.sle_next->field.sle_next);           \
+    }                                                               \
+} while (/*CONSTCOND*/0)
+
+#define QSLIST_FOREACH_RCU(var, head, field)                          \
+    for ((var) = atomic_rcu_read(&(head)->slh_first);                   \
+         (var);                                                         \
+         (var) = atomic_rcu_read(&(var)->field.sle_next))
+
+#define QSLIST_FOREACH_SAFE_RCU(var, head, field, next)                \
+    for ((var) = atomic_rcu_read(&(head)->slh_first);                    \
+         (var) && ((next) = atomic_rcu_read(&(var)->field.sle_next), 1); \
+         (var) = (next))
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 2f1cafed72..edcbd475aa 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -98,6 +98,7 @@ check-unit-y += tests/rcutorture$(EXESUF)
 check-unit-y += tests/test-rcu-list$(EXESUF)
 check-unit-y += tests/test-rcu-simpleq$(EXESUF)
 check-unit-y += tests/test-rcu-tailq$(EXESUF)
+check-unit-y += tests/test-rcu-slist$(EXESUF)
 check-unit-y += tests/test-qdist$(EXESUF)
 check-unit-y += tests/test-qht$(EXESUF)
 check-unit-y += tests/test-qht-par$(EXESUF)
@@ -415,6 +416,7 @@ tests/rcutorture$(EXESUF): tests/rcutorture.o $(test-util-obj-y)
 tests/test-rcu-list$(EXESUF): tests/test-rcu-list.o $(test-util-obj-y)
 tests/test-rcu-simpleq$(EXESUF): tests/test-rcu-simpleq.o $(test-util-obj-y)
 tests/test-rcu-tailq$(EXESUF): tests/test-rcu-tailq.o $(test-util-obj-y)
+tests/test-rcu-slist$(EXESUF): tests/test-rcu-slist.o $(test-util-obj-y)
 tests/test-qdist$(EXESUF): tests/test-qdist.o $(test-util-obj-y)
 tests/test-qht$(EXESUF): tests/test-qht.o $(test-util-obj-y)
 tests/test-qht-par$(EXESUF): tests/test-qht-par.o tests/qht-bench$(EXESUF) $(test-util-obj-y)
diff --git a/tests/test-rcu-list.c b/tests/test-rcu-list.c
index 6f076473e0..1442c0c982 100644
--- a/tests/test-rcu-list.c
+++ b/tests/test-rcu-list.c
@@ -93,6 +93,8 @@ struct list_element {
     QSIMPLEQ_ENTRY(list_element) entry;
 #elif TEST_LIST_TYPE == 3
     QTAILQ_ENTRY(list_element) entry;
+#elif TEST_LIST_TYPE == 4
+    QSLIST_ENTRY(list_element) entry;
 #else
 #error Invalid TEST_LIST_TYPE
 #endif
@@ -144,6 +146,20 @@ static QTAILQ_HEAD(, list_element) Q_list_head;
 #define TEST_LIST_INSERT_HEAD_RCU   QTAILQ_INSERT_HEAD_RCU
 #define TEST_LIST_FOREACH_RCU       QTAILQ_FOREACH_RCU
 #define TEST_LIST_FOREACH_SAFE_RCU  QTAILQ_FOREACH_SAFE_RCU
+
+#elif TEST_LIST_TYPE == 4
+static QSLIST_HEAD(, list_element) Q_list_head;
+
+#define TEST_NAME "qslist"
+#define TEST_LIST_REMOVE_RCU(el, f)                              \
+	 QSLIST_REMOVE_RCU(&Q_list_head, el, list_element, f)
+
+#define TEST_LIST_INSERT_AFTER_RCU(list_el, el, f)               \
+         QSLIST_INSERT_AFTER_RCU(&Q_list_head, list_el, el, f)
+
+#define TEST_LIST_INSERT_HEAD_RCU   QSLIST_INSERT_HEAD_RCU
+#define TEST_LIST_FOREACH_RCU       QSLIST_FOREACH_RCU
+#define TEST_LIST_FOREACH_SAFE_RCU  QSLIST_FOREACH_SAFE_RCU
 #else
 #error Invalid TEST_LIST_TYPE
 #endif
diff --git a/tests/test-rcu-slist.c b/tests/test-rcu-slist.c
new file mode 100644
index 0000000000..868e1e472e
--- /dev/null
+++ b/tests/test-rcu-slist.c
@@ -0,0 +1,2 @@
+#define TEST_LIST_TYPE 4
+#include "test-rcu-list.c"
-- 
2.24.1


  parent reply	other threads:[~2020-02-22  8:54 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-22  8:49 [PULL 00/31] Block patches Stefan Hajnoczi
2020-02-22  8:50 ` [PULL 01/31] virtio: increase virtqueue size for virtio-scsi and virtio-blk Stefan Hajnoczi
2020-02-22  8:50 ` [PULL 02/31] aio-posix: avoid reacquiring rcu_read_lock() when polling Stefan Hajnoczi
2020-02-22  8:50 ` Stefan Hajnoczi [this message]
2020-02-22  8:50 ` [PULL 04/31] util/async: make bh_aio_poll() O(1) Stefan Hajnoczi
2020-03-16 16:42   ` Marc-André Lureau
2020-02-22  8:50 ` [PULL 05/31] aio-posix: fix use after leaving scope in aio_poll() Stefan Hajnoczi
2020-02-22  8:50 ` [PULL 06/31] aio-posix: don't pass ns timeout to epoll_wait() Stefan Hajnoczi
2020-02-22  8:50 ` [PULL 07/31] qemu/queue.h: add QLIST_SAFE_REMOVE() Stefan Hajnoczi
2020-02-22  8:50 ` [PULL 08/31] aio-posix: make AioHandler deletion O(1) Stefan Hajnoczi
2020-02-22  8:50 ` [PULL 09/31] aio-posix: make AioHandler dispatch O(1) with epoll Stefan Hajnoczi
2020-02-22  8:50 ` [PULL 10/31] softmmu: move vl.c to softmmu/ Stefan Hajnoczi
2020-02-22  8:50 ` [PULL 11/31] softmmu: split off vl.c:main() into main.c Stefan Hajnoczi
2020-02-22  8:50 ` [PULL 12/31] module: check module wasn't already initialized Stefan Hajnoczi
2020-02-22  8:50 ` [PULL 13/31] fuzz: add FUZZ_TARGET module type Stefan Hajnoczi
2020-02-22  8:50 ` [PULL 14/31] qtest: add qtest_server_send abstraction Stefan Hajnoczi
2020-02-22  8:50 ` [PULL 15/31] libqtest: add a layer of abstraction to send/recv Stefan Hajnoczi
2020-02-22  8:50 ` [PULL 16/31] libqtest: make bufwrite rely on the TransportOps Stefan Hajnoczi
2020-02-22  8:50 ` [PULL 17/31] qtest: add in-process incoming command handler Stefan Hajnoczi
2020-02-22  8:50 ` [PULL 18/31] libqos: rename i2c_send and i2c_recv Stefan Hajnoczi
2020-02-22  8:50 ` [PULL 19/31] libqos: split qos-test and libqos makefile vars Stefan Hajnoczi
2020-02-22  8:50 ` [PULL 20/31] libqos: move useful qos-test funcs to qos_external Stefan Hajnoczi
2020-02-22  8:50 ` [PULL 21/31] fuzz: add fuzzer skeleton Stefan Hajnoczi
2020-02-22  8:50 ` [PULL 22/31] exec: keep ram block across fork when using qtest Stefan Hajnoczi
2020-02-22  8:50 ` [PULL 23/31] main: keep rcu_atfork callback enabled for qtest Stefan Hajnoczi
2020-02-22  8:50 ` [PULL 24/31] fuzz: support for fork-based fuzzing Stefan Hajnoczi
2020-02-22 11:34   ` Eric Blake
2020-02-24 11:35     ` Stefan Hajnoczi
2020-02-27  2:50       ` Alexander Bulekov
2020-02-22  8:50 ` [PULL 25/31] fuzz: add support for qos-assisted fuzz targets Stefan Hajnoczi
2020-02-22  8:50 ` [PULL 26/31] fuzz: add target/fuzz makefile rules Stefan Hajnoczi
2020-02-22  8:50 ` [PULL 27/31] fuzz: add configure flag --enable-fuzzing Stefan Hajnoczi
2020-02-22  8:50 ` [PULL 28/31] fuzz: add i440fx fuzz targets Stefan Hajnoczi
2020-02-22  8:50 ` [PULL 29/31] fuzz: add virtio-net fuzz target Stefan Hajnoczi
2020-02-22  8:50 ` [PULL 30/31] fuzz: add virtio-scsi " Stefan Hajnoczi
2020-02-22  8:50 ` [PULL 31/31] fuzz: add documentation to docs/devel/ Stefan Hajnoczi
2020-02-22  9:13 ` [PULL 00/31] Block patches no-reply
2020-02-24 11:33   ` Stefan Hajnoczi
2020-02-24 12:47 ` Peter Maydell

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=20200222085030.1760640-4-stefanha@redhat.com \
    --to=stefanha@redhat.com \
    --cc=alxndr@bu.edu \
    --cc=bsd@redhat.com \
    --cc=ehabkost@redhat.com \
    --cc=fam@euphon.net \
    --cc=kwolf@redhat.com \
    --cc=lvivier@redhat.com \
    --cc=marcandre.lureau@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=rth@twiddle.net \
    --cc=thuth@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 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.