From: Roger Pau Monne <roger@xenproject.org>
To: xen-devel@lists.xenproject.org
Cc: alejandro.garciavallejo@amd.com,
Roger Pau Monne <roger@xenproject.org>,
Andrew Cooper <andrew.cooper3@citrix.com>,
Anthony PERARD <anthony.perard@vates.tech>,
Michal Orzel <michal.orzel@amd.com>,
Jan Beulich <jbeulich@suse.com>, Julien Grall <julien@xen.org>,
Stefano Stabellini <sstabellini@kernel.org>
Subject: [PATCH v2 1/3] xen/rcu: introduce the concept of RCU epoch
Date: Fri, 25 Sep 2026 18:30:23 +0200 [thread overview]
Message-ID: <20260925163025.65217-2-roger@xenproject.org> (raw)
In-Reply-To: <20260925163025.65217-1-roger@xenproject.org>
An RCU epoch signals the lifetime of RCU references. Each CPU records the
epoch in force when it enters an RCU critical section. When a callback is
queued the current epoch is stored in the callback and the global epoch is
then bumped, as a way to know when all CPUs have moved past a specific
epoch. At that point there can be no remaining references to objects
fetched during the callback's epoch.
The compiler barrier is switched to a full memory barrier, as future uses
of rcu_lock_cnt must ensure the count is increased before taking a
reference to any RCU protected object.
Access rcu_lock_cnt, rcu_lock_epoch and rcu_epoch through ACCESS_ONCE()
to stop the compiler shattering the loads and stores. The reordering
prevention aspect of ACCESS_ONCE() is not what we rely on here (the memory
barriers cover that); what matters is that these variables now have remote
consumers, so each access must be a single, non-torn memory operation.
Signed-off-by: Roger Pau Monné <roger@xenproject.org>
---
Can possibly be folded into the next patch, as it's lacking context on its
own to understand the need to introduce the logic.
---
Changes since v1:
- Do the setting of head->added in the interrupt disabled section.
- Unconditionally do a memory barrier when enter/exit RCU critical
regions. Attempting to do selectively is too complex.
---
xen/common/rcupdate.c | 6 ++++++
xen/include/xen/rcupdate.h | 17 +++++++++++++----
2 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/xen/common/rcupdate.c b/xen/common/rcupdate.c
index c1b6b2ae768b..babaabbbeefe 100644
--- a/xen/common/rcupdate.c
+++ b/xen/common/rcupdate.c
@@ -49,6 +49,11 @@
#include <asm/atomic.h>
DEFINE_PER_CPU(unsigned int, rcu_lock_cnt);
+/* Store epoch when CPU entered the RCU critical section. */
+DEFINE_PER_CPU(unsigned int, rcu_lock_epoch);
+
+/* Current RCU epoch, bumped every time a new callback is queued. */
+unsigned int rcu_epoch;
/* Global control variables for rcupdate callback mechanism. */
static struct rcu_ctrlblk {
@@ -283,6 +288,7 @@ void call_rcu(struct rcu_head *head,
head->func = func;
head->next = NULL;
local_irq_save(flags);
+ head->added = arch_fetch_and_add(&rcu_epoch, 1);
rdp = &this_cpu(rcu_data);
*rdp->nxttail = head;
rdp->nxttail = &head->next;
diff --git a/xen/include/xen/rcupdate.h b/xen/include/xen/rcupdate.h
index c57f628107cf..5846e8c169d7 100644
--- a/xen/include/xen/rcupdate.h
+++ b/xen/include/xen/rcupdate.h
@@ -34,24 +34,32 @@
#include <xen/compiler.h>
#include <xen/spinlock.h>
#include <xen/cpumask.h>
+#include <xen/lib.h>
#include <xen/percpu.h>
#include <xen/preempt.h>
#define __rcu
DECLARE_PER_CPU(unsigned int, rcu_lock_cnt);
+DECLARE_PER_CPU(unsigned int, rcu_lock_epoch);
+
+extern unsigned int rcu_epoch;
static inline void rcu_quiesce_disable(void)
{
+ unsigned int cpu = smp_processor_id();
+
preempt_disable();
- this_cpu(rcu_lock_cnt)++;
- barrier();
+ if ( !ACCESS_ONCE(per_cpu(rcu_lock_cnt, cpu))++ )
+ ACCESS_ONCE(per_cpu(rcu_lock_epoch, cpu)) = ACCESS_ONCE(rcu_epoch);
+ smp_mb();
}
static inline void rcu_quiesce_enable(void)
{
- barrier();
- this_cpu(rcu_lock_cnt)--;
+
+ smp_mb();
+ ACCESS_ONCE(this_cpu(rcu_lock_cnt))--;
preempt_enable();
}
@@ -68,6 +76,7 @@ static inline bool rcu_quiesce_allowed(void)
struct rcu_head {
struct rcu_head *next;
void (*func)(struct rcu_head *head);
+ unsigned int added;
};
#define RCU_HEAD_INIT { .next = NULL, .func = NULL }
--
2.55.0
next prev parent reply other threads:[~2026-09-25 16:32 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-25 16:30 [PATCH v2 0/3] xen/rcu: rework the RCU logic Roger Pau Monne
2026-09-25 16:30 ` Roger Pau Monne [this message]
2026-09-28 8:24 ` [PATCH v2 1/3] xen/rcu: introduce the concept of RCU epoch Alejandro Vallejo
2026-09-29 14:20 ` Roger Pau Monné
2026-09-29 14:52 ` Jan Beulich
2026-09-29 22:14 ` Alejandro Vallejo
2026-09-30 5:58 ` Jan Beulich
2026-09-30 8:09 ` Roger Pau Monné
2026-09-30 8:34 ` Jan Beulich
2026-09-30 10:07 ` Roger Pau Monné
2026-09-30 10:31 ` Jan Beulich
2026-09-30 11:56 ` Alejandro Vallejo
2026-09-30 8:32 ` Roger Pau Monné
2026-09-30 11:59 ` Alejandro Vallejo
2026-09-25 16:30 ` [PATCH v2 2/3] xen/rcu: simplify RCU implementation Roger Pau Monne
2026-09-28 8:31 ` Alejandro Vallejo
2026-09-28 9:05 ` Alejandro Vallejo
2026-09-29 13:53 ` Roger Pau Monné
2026-09-25 16:30 ` [PATCH v2 3/3] xen/rcu: remove rcu_quiesce_{disable,enable}() Roger Pau Monne
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=20260925163025.65217-2-roger@xenproject.org \
--to=roger@xenproject.org \
--cc=alejandro.garciavallejo@amd.com \
--cc=andrew.cooper3@citrix.com \
--cc=anthony.perard@vates.tech \
--cc=jbeulich@suse.com \
--cc=julien@xen.org \
--cc=michal.orzel@amd.com \
--cc=sstabellini@kernel.org \
--cc=xen-devel@lists.xenproject.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.