This commit accumulates and prints counts of the number and types of hazard-pointer operations that the test performed.
Signed-off-by: Paul E. McKenney <[email protected]> --- include/linux/torture.h | 3 +++ kernel/rcu/hazptrtorture.c | 28 ++++++++++++++++++++++++++-- kernel/torture.c | 15 +++++++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/include/linux/torture.h b/include/linux/torture.h index b8e5d0f3c2d8f9..1b6d5be641f8d5 100644 --- a/include/linux/torture.h +++ b/include/linux/torture.h @@ -136,4 +136,7 @@ void torture_sched_set_normal(struct task_struct *t, int nice); long torture_sched_setaffinity(pid_t pid, const struct cpumask *in_mask, bool dowarn); #endif +/* Atomic per-CPU counters. */ +s64 torture_sum_pcpu_atomic_long(atomic_long_t __percpu *pcp); + #endif /* __LINUX_TORTURE_H */ diff --git a/kernel/rcu/hazptrtorture.c b/kernel/rcu/hazptrtorture.c index fb25f8351659a4..311b387d6ae755 100644 --- a/kernel/rcu/hazptrtorture.c +++ b/kernel/rcu/hazptrtorture.c @@ -81,6 +81,12 @@ static atomic_t n_hazptr_torture_alloc; static atomic_t n_hazptr_torture_alloc_fail; static atomic_t n_hazptr_torture_free; static atomic_t n_hazptr_torture_error; +static DEFINE_PER_CPU(atomic_long_t, hazptr_torture_acquires); +static DEFINE_PER_CPU(atomic_long_t, hazptr_torture_releases); +static DEFINE_PER_CPU(atomic_long_t, hazptr_torture_acquires_irq); +static DEFINE_PER_CPU(atomic_long_t, hazptr_torture_releases_irq); +static DEFINE_PER_CPU(atomic_long_t, hazptr_torture_releases_defer); +static DEFINE_PER_CPU(atomic_long_t, hazptr_torture_releases_undefer); static struct list_head hazptr_torture_removed; // State for a deferred (AKA pending) hazard pointer @@ -364,6 +370,7 @@ static void hazptr_torture_acquire(void *hppp_in) struct hazptr_pending *hppp = hppp_in; hppp->hpp_htp = cur_ops->readlock(&hppp->hpp_hc); + atomic_long_inc(per_cpu_ptr(&hazptr_torture_acquires_irq, raw_smp_processor_id())); } /* @@ -374,6 +381,7 @@ static void hazptr_torture_release(void *hppp_in) struct hazptr_pending *hppp = hppp_in; cur_ops->readunlock(&hppp->hpp_hc, hppp->hpp_htp); + atomic_long_inc(per_cpu_ptr(&hazptr_torture_releases_irq, raw_smp_processor_id())); } /* @@ -407,6 +415,7 @@ hazptr_torture_reader_tail(struct hazptr_pending *hppp, struct torture_random_st smp_call_function_single(cpu, hazptr_torture_release, hppp, 1); } else { cur_ops->readunlock(hcp, htp); + atomic_long_inc(per_cpu_ptr(&hazptr_torture_releases, raw_smp_processor_id())); } } @@ -422,6 +431,7 @@ static void hazptr_torture_defer(struct hazptr_pending *hppp, struct torture_ran cpu = cpumask_next_wrap(cpu, cpu_online_mask); llhp = per_cpu_ptr(&hazptr_pending, cpu); llist_add(&hppp->hpp_node, llhp); + atomic_long_inc(per_cpu_ptr(&hazptr_torture_releases_defer, raw_smp_processor_id())); } /* @@ -455,12 +465,17 @@ static int hazptr_torture_reader(void *arg) if (irq_acquire && !(torture_random(&rand) % irq_acquire)) { guard(preempt)(); cpu = cpumask_next_wrap(cpu, cpu_online_mask); - if (cpu != smp_processor_id()) + if (cpu != smp_processor_id()) { smp_call_function_single(cpu, hazptr_torture_acquire, hppp, 1); - else + } else { hppp->hpp_htp = cur_ops->readlock(&hppp->hpp_hc); + atomic_long_inc(per_cpu_ptr(&hazptr_torture_acquires, + raw_smp_processor_id())); + } } else { hppp->hpp_htp = cur_ops->readlock(&hppp->hpp_hc); + atomic_long_inc(per_cpu_ptr(&hazptr_torture_acquires, + raw_smp_processor_id())); } if (!hppp->hpp_htp) { // Still starting up, so get out of the way. @@ -502,6 +517,8 @@ static void hazptr_torture_do_one_pending(int cpu, struct torture_random_state * return; llist_for_each_entry_safe(hppp, hppp1, llnp, hpp_node) { hazptr_torture_reader_tail(hppp, trsp); + atomic_long_inc(per_cpu_ptr(&hazptr_torture_releases_undefer, + raw_smp_processor_id())); kfree(hppp); } } @@ -611,6 +628,13 @@ hazptr_torture_stats_print(void) atomic_read(&n_hazptr_torture_alloc_fail), atomic_read(&n_hazptr_torture_free)); torture_onoff_stats(); + pr_cont("acq: %lld rel: %lld acqirq: %lld relirq: %lld reldefer: %lld relundefer %lld\n", + torture_sum_pcpu_atomic_long(&hazptr_torture_acquires), + torture_sum_pcpu_atomic_long(&hazptr_torture_releases), + torture_sum_pcpu_atomic_long(&hazptr_torture_acquires_irq), + torture_sum_pcpu_atomic_long(&hazptr_torture_releases_irq), + torture_sum_pcpu_atomic_long(&hazptr_torture_releases_defer), + torture_sum_pcpu_atomic_long(&hazptr_torture_releases_undefer)); pr_alert("%s%s ", torture_type, TORTURE_FLAG); if (i > 1) { diff --git a/kernel/torture.c b/kernel/torture.c index bcd2e9c8a26356..bb9e1349418a19 100644 --- a/kernel/torture.c +++ b/kernel/torture.c @@ -1007,3 +1007,18 @@ void torture_sched_set_normal(struct task_struct *t, int nice) sched_set_normal(t, realnice); } EXPORT_SYMBOL_GPL(torture_sched_set_normal); + +/* + * Sum the specified per-CPU atomic_long_t variable. + */ +s64 torture_sum_pcpu_atomic_long(atomic_long_t __percpu *pcp) +{ + int cpu; + s64 sum = 0; + + for_each_possible_cpu(cpu) { + sum += atomic_long_read(per_cpu_ptr(pcp, cpu)); + } + return sum; +} +EXPORT_SYMBOL_GPL(torture_sum_pcpu_atomic_long); -- 2.40.1

