2023-01-05 01:10:39

by Paul E. McKenney

[permalink] [raw]
Subject: [PATCH rcu 0/9] SRCU updates for v6.3

Hello!

This series provides SRCU updates, perhaps most notably the addition
of a srcu_down_read() and srcu_up_read() that act like srcu_read_lock()
and srcu_read_unlock(), but which permit the srcu_up_read() to be invoked
from a different context than the srcu_down_read().

1. Release early_srcu resources when no longer in use, courtesy
of Zqiang.

2. Delegate work to the boot cpu if using SRCU_SIZE_SMALL, courtesy
of Pingfan Liu.

3. Fix a misspelling in comment, courtesy of Pingfan Liu.

4. Fix the comparision in srcu_invl_snp_seq(), courtesy of Pingfan
Liu.

5. Add srcu_down_read() and srcu_up_read().

6. Add test code for semaphore-like SRCU readers.

7. Remove needless rcu_seq_done() check while holding read lock,
courtesy of Pingfan Liu.

8. Yet more detail for srcu_readers_active_idx_check() comments.

9. Update comment after the index flip.

Thanx, Paul

------------------------------------------------------------------------

b/include/linux/srcu.h | 45 ++++++++++++++++++++++
b/include/linux/srcutree.h | 2 -
b/kernel/rcu/srcutree.c | 9 ++--
b/kernel/rcu/update.c | 1
kernel/rcu/srcutree.c | 89 ++++++++++++++++++++++++++++++++-------------
kernel/rcu/update.c | 3 +
6 files changed, 119 insertions(+), 30 deletions(-)


2023-01-05 01:11:17

by Paul E. McKenney

[permalink] [raw]
Subject: [PATCH rcu 7/9] srcu: Remove needless rcu_seq_done() check while holding read lock

From: Pingfan Liu <[email protected]>

The srcu_gp_start_if_needed() function now read-holds the srcu_struct
whose grace period is being started, which means that the corresponding
SRCU grace period cannot end. This in turn means that the SRCU
grace-period sequence number returned by rcu_seq_snap() cannot expire
during this time. And that means that the calls to rcu_seq_done() in
srcu_funnel_exp_start() and srcu_funnel_gp_start() can never return true.

This commit therefore removes these rcu_seq_done() checks, but adds checks
in kernels built with CONFIG_PROVE_RCU=y that splats if rcu_seq_done()
does somehow return true.

[ paulmck: Rearrange checks to handle kernels built with lockdep. ]

Signed-off-by: Pingfan Liu <[email protected]>
Cc: Lai Jiangshan <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Josh Triplett <[email protected]>
Cc: Steven Rostedt <[email protected]>
Cc: Mathieu Desnoyers <[email protected]>
To: [email protected]
Signed-off-by: Paul E. McKenney <[email protected]>
---
kernel/rcu/srcutree.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c
index 6af0312005801..68b8d8b150db1 100644
--- a/kernel/rcu/srcutree.c
+++ b/kernel/rcu/srcutree.c
@@ -915,7 +915,7 @@ static void srcu_funnel_exp_start(struct srcu_struct *ssp, struct srcu_node *snp
if (snp)
for (; snp != NULL; snp = snp->srcu_parent) {
sgsne = READ_ONCE(snp->srcu_gp_seq_needed_exp);
- if (rcu_seq_done(&ssp->srcu_gp_seq, s) ||
+ if (WARN_ON_ONCE(rcu_seq_done(&ssp->srcu_gp_seq, s)) ||
(!srcu_invl_snp_seq(sgsne) && ULONG_CMP_GE(sgsne, s)))
return;
spin_lock_irqsave_rcu_node(snp, flags);
@@ -942,6 +942,9 @@ static void srcu_funnel_exp_start(struct srcu_struct *ssp, struct srcu_node *snp
*
* Note that this function also does the work of srcu_funnel_exp_start(),
* in some cases by directly invoking it.
+ *
+ * The srcu read lock should be hold around this function. And s is a seq snap
+ * after holding that lock.
*/
static void srcu_funnel_gp_start(struct srcu_struct *ssp, struct srcu_data *sdp,
unsigned long s, bool do_norm)
@@ -962,7 +965,7 @@ static void srcu_funnel_gp_start(struct srcu_struct *ssp, struct srcu_data *sdp,
if (snp_leaf)
/* Each pass through the loop does one level of the srcu_node tree. */
for (snp = snp_leaf; snp != NULL; snp = snp->srcu_parent) {
- if (rcu_seq_done(&ssp->srcu_gp_seq, s) && snp != snp_leaf)
+ if (WARN_ON_ONCE(rcu_seq_done(&ssp->srcu_gp_seq, s)) && snp != snp_leaf)
return; /* GP already done and CBs recorded. */
spin_lock_irqsave_rcu_node(snp, flags);
snp_seq = snp->srcu_have_cbs[idx];
@@ -999,8 +1002,8 @@ static void srcu_funnel_gp_start(struct srcu_struct *ssp, struct srcu_data *sdp,
if (!do_norm && ULONG_CMP_LT(ssp->srcu_gp_seq_needed_exp, s))
WRITE_ONCE(ssp->srcu_gp_seq_needed_exp, s);

- /* If grace period not already done and none in progress, start it. */
- if (!rcu_seq_done(&ssp->srcu_gp_seq, s) &&
+ /* If grace period not already in progress, start it. */
+ if (!WARN_ON_ONCE(rcu_seq_done(&ssp->srcu_gp_seq, s)) &&
rcu_seq_state(ssp->srcu_gp_seq) == SRCU_STATE_IDLE) {
WARN_ON_ONCE(ULONG_CMP_GE(ssp->srcu_gp_seq, ssp->srcu_gp_seq_needed));
srcu_gp_start(ssp);
--
2.31.1.189.g2e36527f23

2023-01-05 01:27:21

by Paul E. McKenney

[permalink] [raw]
Subject: [PATCH rcu 3/9] srcu: Fix a misspelling in comment

From: Pingfan Liu <[email protected]>

s/srcu_gq_seq/srcu_gp_seq/

Signed-off-by: Pingfan Liu <[email protected]>
Cc: Lai Jiangshan <[email protected]>
Cc: Josh Triplett <[email protected]>
Cc: Steven Rostedt <[email protected]>
Cc: Mathieu Desnoyers <[email protected]>
Cc: <[email protected]>
Reviewed-by: Mukesh Ojha <[email protected]>
Reviewed-by: Frederic Weisbecker <[email protected]>
Signed-off-by: Paul E. McKenney <[email protected]>
---
include/linux/srcutree.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/srcutree.h b/include/linux/srcutree.h
index c689a81752c9a..558057b517b74 100644
--- a/include/linux/srcutree.h
+++ b/include/linux/srcutree.h
@@ -49,7 +49,7 @@ struct srcu_data {
struct srcu_node {
spinlock_t __private lock;
unsigned long srcu_have_cbs[4]; /* GP seq for children having CBs, but only */
- /* if greater than ->srcu_gq_seq. */
+ /* if greater than ->srcu_gp_seq. */
unsigned long srcu_data_have_cbs[4]; /* Which srcu_data structs have CBs for given GP? */
unsigned long srcu_gp_seq_needed_exp; /* Furthest future exp GP. */
struct srcu_node *srcu_parent; /* Next up in tree. */
--
2.31.1.189.g2e36527f23