Skip to content

Commit cacba0b

Browse files
paulmckrcuNeeraj Upadhyay (AMD)
authored andcommitted
rcutorture: Print number of RCU up/down readers and migrations
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 <[email protected]> Signed-off-by: Neeraj Upadhyay (AMD) <[email protected]>
1 parent f6c8785 commit cacba0b

File tree

1 file changed

+25
-5
lines changed

1 file changed

+25
-5
lines changed

kernel/rcu/rcutorture.c

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2450,9 +2450,11 @@ struct rcu_torture_one_read_state_updown {
24502450
struct hrtimer rtorsu_hrt;
24512451
bool rtorsu_inuse;
24522452
ktime_t rtorsu_kt;
2453+
int rtorsu_cpu;
24532454
unsigned long rtorsu_j;
24542455
unsigned long rtorsu_ndowns;
24552456
unsigned long rtorsu_nups;
2457+
unsigned long rtorsu_nmigrates;
24562458
struct torture_random_state rtorsu_trs;
24572459
struct rcu_torture_one_read_state rtorsu_rtors;
24582460
};
@@ -2463,12 +2465,15 @@ static int rcu_torture_updown(void *arg);
24632465

24642466
static enum hrtimer_restart rcu_torture_updown_hrt(struct hrtimer *hrtp)
24652467
{
2468+
int cpu = raw_smp_processor_id();
24662469
struct rcu_torture_one_read_state_updown *rtorsup;
24672470

24682471
rtorsup = container_of(hrtp, struct rcu_torture_one_read_state_updown, rtorsu_hrt);
24692472
rcu_torture_one_read_end(&rtorsup->rtorsu_rtors, &rtorsup->rtorsu_trs, -1);
24702473
WARN_ONCE(rtorsup->rtorsu_nups >= rtorsup->rtorsu_ndowns, "%s: Up without matching down #%zu.\n", __func__, rtorsup - updownreaders);
2471-
rtorsup->rtorsu_nups++;
2474+
WRITE_ONCE(rtorsup->rtorsu_nups, rtorsup->rtorsu_nups + 1);
2475+
WRITE_ONCE(rtorsup->rtorsu_nmigrates,
2476+
rtorsup->rtorsu_nmigrates + (cpu != rtorsup->rtorsu_cpu));
24722477
smp_store_release(&rtorsup->rtorsu_inuse, false);
24732478
return HRTIMER_NORESTART;
24742479
}
@@ -2516,7 +2521,7 @@ static void rcu_torture_updown_cleanup(void)
25162521
if (hrtimer_cancel(&rtorsup->rtorsu_hrt) || WARN_ON_ONCE(rtorsup->rtorsu_inuse)) {
25172522
rcu_torture_one_read_end(&rtorsup->rtorsu_rtors, &rtorsup->rtorsu_trs, -1);
25182523
WARN_ONCE(rtorsup->rtorsu_nups >= rtorsup->rtorsu_ndowns, "%s: Up without matching down #%zu.\n", __func__, rtorsup - updownreaders);
2519-
rtorsup->rtorsu_nups++;
2524+
WRITE_ONCE(rtorsup->rtorsu_nups, rtorsup->rtorsu_nups + 1);
25202525
smp_store_release(&rtorsup->rtorsu_inuse, false);
25212526
}
25222527

@@ -2534,13 +2539,14 @@ static void rcu_torture_updown_one(struct rcu_torture_one_read_state_updown *rto
25342539

25352540
init_rcu_torture_one_read_state(&rtorsup->rtorsu_rtors, &rtorsup->rtorsu_trs);
25362541
rawidx = cur_ops->down_read();
2537-
rtorsup->rtorsu_ndowns++;
2542+
WRITE_ONCE(rtorsup->rtorsu_ndowns, rtorsup->rtorsu_ndowns + 1);
25382543
idx = (rawidx << RCUTORTURE_RDR_SHIFT_1) & RCUTORTURE_RDR_MASK_1;
25392544
rtorsup->rtorsu_rtors.readstate = idx | RCUTORTURE_RDR_UPDOWN;
25402545
rtorsup->rtorsu_rtors.rtrsp++;
2546+
rtorsup->rtorsu_cpu = raw_smp_processor_id();
25412547
if (!rcu_torture_one_read_start(&rtorsup->rtorsu_rtors, &rtorsup->rtorsu_trs, -1)) {
25422548
WARN_ONCE(rtorsup->rtorsu_nups >= rtorsup->rtorsu_ndowns, "%s: Up without matching down #%zu.\n", __func__, rtorsup - updownreaders);
2543-
rtorsup->rtorsu_nups++;
2549+
WRITE_ONCE(rtorsup->rtorsu_nups, rtorsup->rtorsu_nups + 1);
25442550
schedule_timeout_idle(HZ);
25452551
return;
25462552
}
@@ -2649,6 +2655,10 @@ rcu_torture_stats_print(void)
26492655
long pipesummary[RCU_TORTURE_PIPE_LEN + 1] = { 0 };
26502656
long batchsummary[RCU_TORTURE_PIPE_LEN + 1] = { 0 };
26512657
long n_gpwraps = 0;
2658+
unsigned long ndowns = 0;
2659+
unsigned long nunexpired = 0;
2660+
unsigned long nmigrates = 0;
2661+
unsigned long nups = 0;
26522662
struct rcu_torture *rtcp;
26532663
static unsigned long rtcv_snap = ULONG_MAX;
26542664
static bool splatted;
@@ -2662,10 +2672,18 @@ rcu_torture_stats_print(void)
26622672
if (cur_ops->get_gpwrap_count)
26632673
n_gpwraps += cur_ops->get_gpwrap_count(cpu);
26642674
}
2675+
if (updownreaders) {
2676+
for (i = 0; i < n_up_down; i++) {
2677+
ndowns += READ_ONCE(updownreaders[i].rtorsu_ndowns);
2678+
nups += READ_ONCE(updownreaders[i].rtorsu_nups);
2679+
nunexpired += READ_ONCE(updownreaders[i].rtorsu_inuse);
2680+
nmigrates += READ_ONCE(updownreaders[i].rtorsu_nmigrates);
2681+
}
2682+
}
26652683
for (i = RCU_TORTURE_PIPE_LEN; i >= 0; i--) {
26662684
if (pipesummary[i] != 0)
26672685
break;
2668-
}
2686+
} // The value of variable "i" is used later, so don't clobber it!
26692687

26702688
pr_alert("%s%s ", torture_type, TORTURE_FLAG);
26712689
rtcp = rcu_access_pointer(rcu_torture_current);
@@ -2686,6 +2704,8 @@ rcu_torture_stats_print(void)
26862704
n_rcu_torture_boost_failure,
26872705
n_rcu_torture_boosts,
26882706
atomic_long_read(&n_rcu_torture_timers));
2707+
if (updownreaders)
2708+
pr_cont("ndowns: %lu nups: %lu nhrt: %lu nmigrates: %lu ", ndowns, nups, nunexpired, nmigrates);
26892709
torture_onoff_stats();
26902710
pr_cont("barrier: %ld/%ld:%ld ",
26912711
data_race(n_barrier_successes),

0 commit comments

Comments
 (0)