From: Roger Pau Monne <roger@xenproject.org>
To: xen-devel@lists.xenproject.org
Cc: "Jürgen Groß" <jgross@suse.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 3/5] xen/rcu: introduce the concept of RCU epoch
Date: Fri, 4 Sep 2026 19:11:19 +0200 [thread overview]
Message-ID: <20260904171121.65300-4-roger@xenproject.org> (raw)
In-Reply-To: <20260904171121.65300-1-roger@xenproject.org>
An RCU epoch signals the lifetime of RCU references. Each CPU keeps track
of the epoch when an RCU critical section is entered. When a RCU callback
is added the current epoch is recorded in the callback, and increased, as a
way to know when all CPUs have moved past a specific epoch, and thus there
are no longer active references to objects fetched during that 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.
Use ACCESS_ONCE() avoid the compiler from shattering accesses to the
variables. The reordering prevention aspect of ACCESS_ONCE() is not
relevant here, but we must ensure accesses are not shattered, as there will
be remote consumers of those variables.
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.
---
xen/common/rcupdate.c | 6 ++++++
xen/include/xen/rcupdate.h | 19 +++++++++++++++----
2 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/xen/common/rcupdate.c b/xen/common/rcupdate.c
index c1b6b2ae768b..bd63280fd63c 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 {
@@ -282,6 +287,7 @@ void call_rcu(struct rcu_head *head,
head->func = func;
head->next = NULL;
+ head->added = arch_fetch_and_add(&rcu_epoch, 1);
local_irq_save(flags);
rdp = &this_cpu(rcu_data);
*rdp->nxttail = head;
diff --git a/xen/include/xen/rcupdate.h b/xen/include/xen/rcupdate.h
index c57f628107cf..6c265c672c14 100644
--- a/xen/include/xen/rcupdate.h
+++ b/xen/include/xen/rcupdate.h
@@ -34,24 +34,34 @@
#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)--;
+ if ( this_cpu(rcu_lock_cnt) == 1 )
+ smp_mb();
+ ACCESS_ONCE(this_cpu(rcu_lock_cnt))--;
preempt_enable();
}
@@ -68,6 +78,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.53.0
next prev parent reply other threads:[~2026-09-04 17:14 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-04 17:11 [PATCH 0/5] xen/rcu: rework the RCU logic Roger Pau Monne
2026-09-04 17:11 ` [PATCH 1/5] xen/rcu: fix types Roger Pau Monne
2026-09-04 18:32 ` Andrew Cooper
2026-09-04 17:11 ` [PATCH 2/5] xen/rcu: sort includes Roger Pau Monne
2026-09-04 18:33 ` Andrew Cooper
2026-09-04 17:11 ` Roger Pau Monne [this message]
2026-09-04 17:11 ` [PATCH 4/5] xen/rcu: simplify RCU implementation Roger Pau Monne
2026-09-04 17:11 ` [PATCH 5/5] xen/rcu: remove rcu_needs_cpu() 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=20260904171121.65300-4-roger@xenproject.org \
--to=roger@xenproject.org \
--cc=andrew.cooper3@citrix.com \
--cc=anthony.perard@vates.tech \
--cc=jbeulich@suse.com \
--cc=jgross@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.