Skip to content

Commit 62d92c9

Browse files
paulmckrcuNeeraj Upadhyay (AMD)
authored andcommitted
rcutorture: Complain if an ->up_read() is delayed more than 10 seconds
The down/up SRCU reader testing uses an hrtimer handler to exit the SRCU read-side critical section. This might be delayed, and if delayed for too long, it can prevent the rcutorture run from completing. This commit therefore complains if the hrtimer handler is delayed for more than ten seconds. [ paulmck, joel: Apply kernel test robot feedback to avoid false-positive complaint of excessive ->up_read() delays by using HRTIMER_MODE_HARD ] Tested-by: kernel test robot <[email protected]> Signed-off-by: Paul E. McKenney <[email protected]> Signed-off-by: Joel Fernandes <[email protected]> Signed-off-by: Neeraj Upadhyay (AMD) <[email protected]>
1 parent 065de24 commit 62d92c9

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

kernel/rcu/rcutorture.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2447,6 +2447,8 @@ rcu_torture_reader(void *arg)
24472447
struct rcu_torture_one_read_state_updown {
24482448
struct hrtimer rtorsu_hrt;
24492449
bool rtorsu_inuse;
2450+
ktime_t rtorsu_kt;
2451+
unsigned long rtorsu_j;
24502452
struct torture_random_state rtorsu_trs;
24512453
struct rcu_torture_one_read_state rtorsu_rtors;
24522454
};
@@ -2485,7 +2487,7 @@ static int rcu_torture_updown_init(void)
24852487
for (i = 0; i < n_up_down; i++) {
24862488
init_rcu_torture_one_read_state(&updownreaders[i].rtorsu_rtors, rand);
24872489
hrtimer_setup(&updownreaders[i].rtorsu_hrt, rcu_torture_updown_hrt, CLOCK_MONOTONIC,
2488-
HRTIMER_MODE_REL | HRTIMER_MODE_SOFT);
2490+
HRTIMER_MODE_REL | HRTIMER_MODE_HARD);
24892491
torture_random_init(&updownreaders[i].rtorsu_trs);
24902492
init_rcu_torture_one_read_state(&updownreaders[i].rtorsu_rtors,
24912493
&updownreaders[i].rtorsu_trs);
@@ -2533,7 +2535,10 @@ static void rcu_torture_updown_one(struct rcu_torture_one_read_state_updown *rto
25332535
t = torture_random(&rtorsup->rtorsu_trs) & 0xfffff; // One per million.
25342536
if (t < 10 * 1000)
25352537
t = 200 * 1000 * 1000;
2536-
hrtimer_start(&rtorsup->rtorsu_hrt, t, HRTIMER_MODE_REL | HRTIMER_MODE_SOFT);
2538+
hrtimer_start(&rtorsup->rtorsu_hrt, t, HRTIMER_MODE_REL | HRTIMER_MODE_HARD);
2539+
smp_mb(); // Sample jiffies after posting hrtimer.
2540+
rtorsup->rtorsu_j = jiffies; // Not used by hrtimer handler.
2541+
rtorsup->rtorsu_kt = t;
25372542
}
25382543

25392544
/*
@@ -2544,15 +2549,20 @@ static void rcu_torture_updown_one(struct rcu_torture_one_read_state_updown *rto
25442549
static int
25452550
rcu_torture_updown(void *arg)
25462551
{
2552+
unsigned long j;
25472553
struct rcu_torture_one_read_state_updown *rtorsup;
25482554

25492555
VERBOSE_TOROUT_STRING("rcu_torture_updown task started");
25502556
do {
25512557
for (rtorsup = updownreaders; rtorsup < &updownreaders[n_up_down]; rtorsup++) {
25522558
if (torture_must_stop())
25532559
break;
2554-
if (smp_load_acquire(&rtorsup->rtorsu_inuse))
2560+
j = smp_load_acquire(&jiffies); // Time before ->rtorsu_inuse.
2561+
if (smp_load_acquire(&rtorsup->rtorsu_inuse)) {
2562+
WARN_ONCE(time_after(j, rtorsup->rtorsu_j + 1 + HZ * 10),
2563+
"hrtimer queued at jiffies %lu for %lld ns took %lu jiffies\n", rtorsup->rtorsu_j, rtorsup->rtorsu_kt, j - rtorsup->rtorsu_j);
25552564
continue;
2565+
}
25562566
rcu_torture_updown_one(rtorsup);
25572567
}
25582568
torture_hrtimeout_ms(1, 1000, &rcu_torture_updown_rand);

0 commit comments

Comments
 (0)