* [PATCH 1/5] torture: Suppress torture.sh "Zero time" messages for disabled tests
2025-05-08 23:44 [PATCH 0/5] Miscellaneous rcutorture updates Paul E. McKenney
@ 2025-05-08 23:44 ` Paul E. McKenney
2025-05-08 23:44 ` [PATCH 2/5] rcutorture: Print number of RCU up/down readers and migrations Paul E. McKenney
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Paul E. McKenney @ 2025-05-08 23:44 UTC (permalink / raw)
To: rcu; +Cc: linux-kernel, kernel-team, rostedt, Paul E. McKenney
The torture.sh script prints " --- Zero time for locktorture, disabling"
when the --duration parameter is too short to allow the test to run
even when locktorture has been disabled, for example, via --do-none.
The same is true for scftorture and rcutorture.
This commit therefore suppresses this message when the corresponding
test has been disabled.
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
---
tools/testing/selftests/rcutorture/bin/torture.sh | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tools/testing/selftests/rcutorture/bin/torture.sh b/tools/testing/selftests/rcutorture/bin/torture.sh
index e03fdaca89b35..c518de2968711 100755
--- a/tools/testing/selftests/rcutorture/bin/torture.sh
+++ b/tools/testing/selftests/rcutorture/bin/torture.sh
@@ -274,7 +274,7 @@ then
configs_rcutorture=CFLIST
fi
duration_rcutorture=$((duration_base*duration_rcutorture_frac/10))
-if test "$duration_rcutorture" -eq 0
+if test "$duration_rcutorture" -eq 0 && test "$do_locktorture" = "yes"
then
echo " --- Zero time for rcutorture, disabling" | tee -a $T/log
do_rcutorture=no
@@ -286,7 +286,7 @@ then
configs_locktorture=CFLIST
fi
duration_locktorture=$((duration_base*duration_locktorture_frac/10))
-if test "$duration_locktorture" -eq 0
+if test "$duration_locktorture" -eq 0 && test "$do_locktorture" = "yes"
then
echo " --- Zero time for locktorture, disabling" | tee -a $T/log
do_locktorture=no
@@ -298,7 +298,7 @@ then
configs_scftorture=CFLIST
fi
duration_scftorture=$((duration_base*duration_scftorture_frac/10))
-if test "$duration_scftorture" -eq 0
+if test "$duration_scftorture" -eq 0 && test "$do_scftorture" = "yes"
then
echo " --- Zero time for scftorture, disabling" | tee -a $T/log
do_scftorture=no
--
2.40.1
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH 2/5] rcutorture: Print number of RCU up/down readers and migrations
2025-05-08 23:44 [PATCH 0/5] Miscellaneous rcutorture updates Paul E. McKenney
2025-05-08 23:44 ` [PATCH 1/5] torture: Suppress torture.sh "Zero time" messages for disabled tests Paul E. McKenney
@ 2025-05-08 23:44 ` Paul E. McKenney
2025-05-08 23:45 ` [PATCH 3/5] rcutorture: Check for no up/down readers at task level Paul E. McKenney
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Paul E. McKenney @ 2025-05-08 23:44 UTC (permalink / raw)
To: rcu; +Cc: linux-kernel, kernel-team, rostedt, Paul E. McKenney
This commit prints the number of RCU up/down readers and the number
of such readers that migrated from one CPU to another, along
with the rest of the periodic rcu_torture_stats_print() output.
These statistics are currently used only by srcu_down_read{,_fast}()
and srcu_up_read(,_fast)().
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
---
kernel/rcu/rcutorture.c | 30 +++++++++++++++++++++++++-----
1 file changed, 25 insertions(+), 5 deletions(-)
diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
index 0e044afa98d32..21ff365fca5d9 100644
--- a/kernel/rcu/rcutorture.c
+++ b/kernel/rcu/rcutorture.c
@@ -2447,9 +2447,11 @@ struct rcu_torture_one_read_state_updown {
struct hrtimer rtorsu_hrt;
bool rtorsu_inuse;
ktime_t rtorsu_kt;
+ int rtorsu_cpu;
unsigned long rtorsu_j;
unsigned long rtorsu_ndowns;
unsigned long rtorsu_nups;
+ unsigned long rtorsu_nmigrates;
struct torture_random_state rtorsu_trs;
struct rcu_torture_one_read_state rtorsu_rtors;
};
@@ -2460,12 +2462,15 @@ static int rcu_torture_updown(void *arg);
static enum hrtimer_restart rcu_torture_updown_hrt(struct hrtimer *hrtp)
{
+ int cpu = raw_smp_processor_id();
struct rcu_torture_one_read_state_updown *rtorsup;
rtorsup = container_of(hrtp, struct rcu_torture_one_read_state_updown, rtorsu_hrt);
rcu_torture_one_read_end(&rtorsup->rtorsu_rtors, &rtorsup->rtorsu_trs, -1);
WARN_ONCE(rtorsup->rtorsu_nups >= rtorsup->rtorsu_ndowns, "%s: Up without matching down #%zu.\n", __func__, rtorsup - updownreaders);
- rtorsup->rtorsu_nups++;
+ WRITE_ONCE(rtorsup->rtorsu_nups, rtorsup->rtorsu_nups + 1);
+ WRITE_ONCE(rtorsup->rtorsu_nmigrates,
+ rtorsup->rtorsu_nmigrates + (cpu != rtorsup->rtorsu_cpu));
smp_store_release(&rtorsup->rtorsu_inuse, false);
return HRTIMER_NORESTART;
}
@@ -2513,7 +2518,7 @@ static void rcu_torture_updown_cleanup(void)
if (hrtimer_cancel(&rtorsup->rtorsu_hrt) || WARN_ON_ONCE(rtorsup->rtorsu_inuse)) {
rcu_torture_one_read_end(&rtorsup->rtorsu_rtors, &rtorsup->rtorsu_trs, -1);
WARN_ONCE(rtorsup->rtorsu_nups >= rtorsup->rtorsu_ndowns, "%s: Up without matching down #%zu.\n", __func__, rtorsup - updownreaders);
- rtorsup->rtorsu_nups++;
+ WRITE_ONCE(rtorsup->rtorsu_nups, rtorsup->rtorsu_nups + 1);
smp_store_release(&rtorsup->rtorsu_inuse, false);
}
@@ -2531,13 +2536,14 @@ static void rcu_torture_updown_one(struct rcu_torture_one_read_state_updown *rto
init_rcu_torture_one_read_state(&rtorsup->rtorsu_rtors, &rtorsup->rtorsu_trs);
rawidx = cur_ops->down_read();
- rtorsup->rtorsu_ndowns++;
+ WRITE_ONCE(rtorsup->rtorsu_ndowns, rtorsup->rtorsu_ndowns + 1);
idx = (rawidx << RCUTORTURE_RDR_SHIFT_1) & RCUTORTURE_RDR_MASK_1;
rtorsup->rtorsu_rtors.readstate = idx | RCUTORTURE_RDR_UPDOWN;
rtorsup->rtorsu_rtors.rtrsp++;
+ rtorsup->rtorsu_cpu = raw_smp_processor_id();
if (!rcu_torture_one_read_start(&rtorsup->rtorsu_rtors, &rtorsup->rtorsu_trs, -1)) {
WARN_ONCE(rtorsup->rtorsu_nups >= rtorsup->rtorsu_ndowns, "%s: Up without matching down #%zu.\n", __func__, rtorsup - updownreaders);
- rtorsup->rtorsu_nups++;
+ WRITE_ONCE(rtorsup->rtorsu_nups, rtorsup->rtorsu_nups + 1);
schedule_timeout_idle(HZ);
return;
}
@@ -2646,6 +2652,10 @@ rcu_torture_stats_print(void)
long pipesummary[RCU_TORTURE_PIPE_LEN + 1] = { 0 };
long batchsummary[RCU_TORTURE_PIPE_LEN + 1] = { 0 };
long n_gpwraps = 0;
+ unsigned long ndowns = 0;
+ unsigned long nunexpired = 0;
+ unsigned long nmigrates = 0;
+ unsigned long nups = 0;
struct rcu_torture *rtcp;
static unsigned long rtcv_snap = ULONG_MAX;
static bool splatted;
@@ -2659,10 +2669,18 @@ rcu_torture_stats_print(void)
if (cur_ops->get_gpwrap_count)
n_gpwraps += cur_ops->get_gpwrap_count(cpu);
}
+ if (updownreaders) {
+ for (i = 0; i < n_up_down; i++) {
+ ndowns += READ_ONCE(updownreaders[i].rtorsu_ndowns);
+ nups += READ_ONCE(updownreaders[i].rtorsu_nups);
+ nunexpired += READ_ONCE(updownreaders[i].rtorsu_inuse);
+ nmigrates += READ_ONCE(updownreaders[i].rtorsu_nmigrates);
+ }
+ }
for (i = RCU_TORTURE_PIPE_LEN; i >= 0; i--) {
if (pipesummary[i] != 0)
break;
- }
+ } // The value of variable "i" is used later, so don't clobber it!
pr_alert("%s%s ", torture_type, TORTURE_FLAG);
rtcp = rcu_access_pointer(rcu_torture_current);
@@ -2683,6 +2701,8 @@ rcu_torture_stats_print(void)
n_rcu_torture_boost_failure,
n_rcu_torture_boosts,
atomic_long_read(&n_rcu_torture_timers));
+ if (updownreaders)
+ pr_cont("ndowns: %lu nups: %lu nhrt: %lu nmigrates: %lu ", ndowns, nups, nunexpired, nmigrates);
torture_onoff_stats();
pr_cont("barrier: %ld/%ld:%ld ",
data_race(n_barrier_successes),
--
2.40.1
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH 3/5] rcutorture: Check for no up/down readers at task level
2025-05-08 23:44 [PATCH 0/5] Miscellaneous rcutorture updates Paul E. McKenney
2025-05-08 23:44 ` [PATCH 1/5] torture: Suppress torture.sh "Zero time" messages for disabled tests Paul E. McKenney
2025-05-08 23:44 ` [PATCH 2/5] rcutorture: Print number of RCU up/down readers and migrations Paul E. McKenney
@ 2025-05-08 23:45 ` Paul E. McKenney
2025-05-08 23:45 ` [PATCH 4/5] rcutorture: Start rcu_torture_writer() after rcu_torture_reader() Paul E. McKenney
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Paul E. McKenney @ 2025-05-08 23:45 UTC (permalink / raw)
To: rcu; +Cc: linux-kernel, kernel-team, rostedt, Paul E. McKenney
The design of testing of up/down readers such as srcu_down_read()
and srcu_up_read() assumes that these are tested only by the
rcu_torture_updown() kthread, and never by the rcu_torture_reader()
kthread. Because we all know which road is paved with good intentions,
this commit adds WARN_ON_ONCE() to verify that things are going to plan.
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
---
kernel/rcu/rcutorture.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
index 21ff365fca5d9..d94b24f19cf59 100644
--- a/kernel/rcu/rcutorture.c
+++ b/kernel/rcu/rcutorture.c
@@ -2231,6 +2231,7 @@ rcutorture_loop_extend(int *readstate, bool insoftirq, struct torture_random_sta
i = ((i | (i >> 3)) & RCUTORTURE_RDR_MAX_LOOPS) + 1;
for (j = 0; j < i; j++) {
mask = rcutorture_extend_mask(*readstate, trsp);
+ WARN_ON_ONCE(mask & RCUTORTURE_RDR_UPDOWN);
rcutorture_one_extend(readstate, mask, insoftirq, trsp, &rtrsp[j]);
}
return &rtrsp[j];
@@ -2367,6 +2368,7 @@ static bool rcu_torture_one_read(struct torture_random_state *trsp, long myid)
WARN_ON_ONCE(!rcu_is_watching());
init_rcu_torture_one_read_state(&rtors, trsp);
newstate = rcutorture_extend_mask(rtors.readstate, trsp);
+ WARN_ON_ONCE(newstate & RCUTORTURE_RDR_UPDOWN);
rcutorture_one_extend(&rtors.readstate, newstate, myid < 0, trsp, rtors.rtrsp++);
if (!rcu_torture_one_read_start(&rtors, trsp, myid)) {
rcutorture_one_extend(&rtors.readstate, 0, myid < 0, trsp, rtors.rtrsp);
--
2.40.1
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH 4/5] rcutorture: Start rcu_torture_writer() after rcu_torture_reader()
2025-05-08 23:44 [PATCH 0/5] Miscellaneous rcutorture updates Paul E. McKenney
` (2 preceding siblings ...)
2025-05-08 23:45 ` [PATCH 3/5] rcutorture: Check for no up/down readers at task level Paul E. McKenney
@ 2025-05-08 23:45 ` Paul E. McKenney
2025-05-08 23:45 ` [PATCH 5/5] rcutorture: Print only one rtort_pipe_count splat Paul E. McKenney
2025-05-09 13:16 ` [PATCH 0/5] Miscellaneous rcutorture updates Joel Fernandes
5 siblings, 0 replies; 7+ messages in thread
From: Paul E. McKenney @ 2025-05-08 23:45 UTC (permalink / raw)
To: rcu
Cc: linux-kernel, kernel-team, rostedt, Paul E. McKenney,
Joel Fernandes, Boqun Feng
Testing of rcutorture's SRCU-P scenario on a large arm64 system resulted
in rcu_torture_writer() forward-progress failures, but these same tests
passed on x86. After some off-list discussion of possible memory-ordering
causes for these failures, Boqun showed that these were in fact due to
reordering, but by the scheduler, not by the memory system. On x86,
rcu_torture_writer() would have run quickly enough that by the time
the rcu_torture_updown() kthread started, the rcu_torture_current
variable would already be initialized, thus avoiding a bug in which
a NULL value would cause rcu_torture_updown() to do an extra call to
srcu_up_read_fast().
This commit therefore moves creation of the rcu_torture_writer() kthread
after that of the rcu_torture_reader() kthreads. This results in
deterministic failures on x86.
What about the double-srcu_up_read_fast() bug? Boqun has the fix.
But let's also fix the test while we are at it!
Reported-by: Joel Fernandes <joelagnelf@nvidia.com>
Reported-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
---
kernel/rcu/rcutorture.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
index d94b24f19cf59..62f082e24d3b9 100644
--- a/kernel/rcu/rcutorture.c
+++ b/kernel/rcu/rcutorture.c
@@ -4476,11 +4476,6 @@ rcu_torture_init(void)
/* Start up the kthreads. */
rcu_torture_write_types();
- firsterr = torture_create_kthread(rcu_torture_writer, NULL,
- writer_task);
- if (torture_init_error(firsterr))
- goto unwind;
-
if (nrealfakewriters > 0) {
fakewriter_tasks = kcalloc(nrealfakewriters,
sizeof(fakewriter_tasks[0]),
@@ -4516,6 +4511,11 @@ rcu_torture_init(void)
firsterr = rcu_torture_updown_init();
if (torture_init_error(firsterr))
goto unwind;
+ firsterr = torture_create_kthread(rcu_torture_writer, NULL,
+ writer_task);
+ if (torture_init_error(firsterr))
+ goto unwind;
+
nrealnocbers = nocbs_nthreads;
if (WARN_ON(nrealnocbers < 0))
nrealnocbers = 1;
--
2.40.1
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH 5/5] rcutorture: Print only one rtort_pipe_count splat
2025-05-08 23:44 [PATCH 0/5] Miscellaneous rcutorture updates Paul E. McKenney
` (3 preceding siblings ...)
2025-05-08 23:45 ` [PATCH 4/5] rcutorture: Start rcu_torture_writer() after rcu_torture_reader() Paul E. McKenney
@ 2025-05-08 23:45 ` Paul E. McKenney
2025-05-09 13:16 ` [PATCH 0/5] Miscellaneous rcutorture updates Joel Fernandes
5 siblings, 0 replies; 7+ messages in thread
From: Paul E. McKenney @ 2025-05-08 23:45 UTC (permalink / raw)
To: rcu; +Cc: linux-kernel, kernel-team, rostedt, Paul E. McKenney
The rcu_torture_writer() function scans the memory blocks after a stutter
(or forced idle) interval, complaining about any that have not passed
through ten grace periods since the start of the stutter interval.
But one splat suffices, so this commit therefore stops at the first splat.
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
---
kernel/rcu/rcutorture.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
index 62f082e24d3b9..2699f47557bf7 100644
--- a/kernel/rcu/rcutorture.c
+++ b/kernel/rcu/rcutorture.c
@@ -1781,6 +1781,7 @@ rcu_torture_writer(void *arg)
cur_ops->gp_kthread_dbg();
WARN(1, "%s: rtort_pipe_count: %d\n", __func__, rcu_tortures[i].rtort_pipe_count);
rcu_ftrace_dump(DUMP_ALL);
+ break;
}
if (stutter_waited)
sched_set_normal(current, oldnice);
--
2.40.1
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH 0/5] Miscellaneous rcutorture updates
2025-05-08 23:44 [PATCH 0/5] Miscellaneous rcutorture updates Paul E. McKenney
` (4 preceding siblings ...)
2025-05-08 23:45 ` [PATCH 5/5] rcutorture: Print only one rtort_pipe_count splat Paul E. McKenney
@ 2025-05-09 13:16 ` Joel Fernandes
5 siblings, 0 replies; 7+ messages in thread
From: Joel Fernandes @ 2025-05-09 13:16 UTC (permalink / raw)
To: paulmck, rcu; +Cc: linux-kernel, kernel-team, rostedt
On 5/8/2025 7:44 PM, Paul E. McKenney wrote:
> Hello!
>
> This series provides miscellaneous rcutorture updates:
>
> 1. Suppress torture.sh "Zero time" messages for disabled tests.
>
> 2. Print number of RCU up/down readers and migrations.
>
> 3. Check for no up/down readers at task level.
>
> 4. Start rcu_torture_writer() after rcu_torture_reader().
>
> 5. Print only one rtort_pipe_count splat.
Paul,
Are these for 6.16? I am guessing not so I'll put them in my rcu/dev branch but
let me know.
Thanks.
^ permalink raw reply [flat|nested] 7+ messages in thread