unsigned long rt_delay_us;
bool rt_preempted;
int rt_cpu;
+ int rt_end_cpu;
};
static int err_segs_recorded;
static struct rt_read_seg err_segs[RCUTORTURE_RDR_MAX_SEGS];
static int rt_read_nsegs;
static int rt_read_preempted;
-static int rt_last_cpu;
static const char *rcu_torture_writer_state_getname(void)
{
struct torture_random_state *trsp,
struct rt_read_seg *rtrsp)
{
+ bool first;
unsigned long flags;
int idxnew1 = -1;
int idxnew2 = -1;
int statesnew = ~*readstate & newstate;
int statesold = *readstate & ~newstate;
+ first = idxold1 == 0;
WARN_ON_ONCE(idxold2 < 0);
WARN_ON_ONCE(idxold2 & ~RCUTORTURE_RDR_ALLBITS);
rcutorture_one_extend_check("before change", idxold1, statesnew, statesold, insoftirq);
rtrsp->rt_readstate = newstate;
- if (IS_ENABLED(CONFIG_RCU_TORTURE_TEST_LOG_CPU))
- rtrsp->rt_cpu = raw_smp_processor_id();
/* First, put new protection in place to avoid critical-section gap. */
if (statesnew & RCUTORTURE_RDR_BH)
rcutorture_one_extend_check("during change",
idxold1 | statesnew, statesnew, statesold, insoftirq);
+ // Sample CPU under both sets of protections to reduce confusion.
+ if (IS_ENABLED(CONFIG_RCU_TORTURE_TEST_LOG_CPU)) {
+ int cpu = raw_smp_processor_id();
+ rtrsp->rt_cpu = cpu;
+ if (!first)
+ rtrsp[-1].rt_end_cpu = cpu;
+ }
+
/*
* Next, remove old protection, in decreasing order of strength
* to avoid unlock paths that aren't safe in the stronger
}
if (cur_ops->reader_blocked)
preempted = cur_ops->reader_blocked();
- if (IS_ENABLED(CONFIG_RCU_TORTURE_TEST_LOG_CPU))
- rt_last_cpu = raw_smp_processor_id();
rcutorture_one_extend(&readstate, 0, myid < 0, trsp, rtrsp);
WARN_ON_ONCE(readstate);
// This next splat is expected behavior if leakpointer, especially
err_segs[i].rt_delay_jiffies);
firsttime = 0;
}
- if (IS_ENABLED(CONFIG_RCU_TORTURE_TEST_LOG_CPU))
- pr_cont(" CPU %-2d", err_segs[i].rt_cpu);
+ if (IS_ENABLED(CONFIG_RCU_TORTURE_TEST_LOG_CPU)) {
+ pr_cont(" CPU %2d", err_segs[i].rt_cpu);
+ if (err_segs[i].rt_cpu != err_segs[i].rt_end_cpu)
+ pr_cont("->%-2d", err_segs[i].rt_end_cpu);
+ else
+ pr_cont(" ...");
+ }
if (err_segs[i].rt_delay_ms != 0) {
pr_cont(" %s%ldms", firsttime ? "" : "+",
err_segs[i].rt_delay_ms);
}
if (rt_read_preempted)
pr_alert("\tReader was preempted.\n");
- if (IS_ENABLED(CONFIG_RCU_TORTURE_TEST_LOG_CPU))
- pr_alert("\tReader last ran on CPU %d.\n", rt_last_cpu);
}
if (atomic_read(&n_rcu_torture_error) || n_rcu_torture_barrier_error)
rcu_torture_print_module_parms(cur_ops, "End of test: FAILURE");