refscale: Add acqrel, lock, and lock-irq
authorPaul E. McKenney <paulmck@kernel.org>
Thu, 11 Mar 2021 02:02:36 +0000 (18:02 -0800)
committerPaul E. McKenney <paulmck@kernel.org>
Mon, 10 May 2021 23:05:05 +0000 (16:05 -0700)
This commit adds scale_type of acqrel, lock, and lock-irq to
test acquisition and release.  Note that the refscale.nreaders=1
module parameter is required if you wish to test uncontended locking.
In contrast, acqrel uses a per-CPU variable, so should be just fine with
large values of the refscale.nreaders=1 module parameter.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
kernel/rcu/refscale.c

index 02dd976..313d454 100644 (file)
@@ -362,6 +362,111 @@ static struct ref_scale_ops rwsem_ops = {
        .name           = "rwsem"
 };
 
+// Definitions for global spinlock
+static DEFINE_SPINLOCK(test_lock);
+
+static void ref_lock_section(const int nloops)
+{
+       int i;
+
+       preempt_disable();
+       for (i = nloops; i >= 0; i--) {
+               spin_lock(&test_lock);
+               spin_unlock(&test_lock);
+       }
+       preempt_enable();
+}
+
+static void ref_lock_delay_section(const int nloops, const int udl, const int ndl)
+{
+       int i;
+
+       preempt_disable();
+       for (i = nloops; i >= 0; i--) {
+               spin_lock(&test_lock);
+               un_delay(udl, ndl);
+               spin_unlock(&test_lock);
+       }
+       preempt_enable();
+}
+
+static struct ref_scale_ops lock_ops = {
+       .readsection    = ref_lock_section,
+       .delaysection   = ref_lock_delay_section,
+       .name           = "lock"
+};
+
+// Definitions for global irq-save spinlock
+
+static void ref_lock_irq_section(const int nloops)
+{
+       unsigned long flags;
+       int i;
+
+       preempt_disable();
+       for (i = nloops; i >= 0; i--) {
+               spin_lock_irqsave(&test_lock, flags);
+               spin_unlock_irqrestore(&test_lock, flags);
+       }
+       preempt_enable();
+}
+
+static void ref_lock_irq_delay_section(const int nloops, const int udl, const int ndl)
+{
+       unsigned long flags;
+       int i;
+
+       preempt_disable();
+       for (i = nloops; i >= 0; i--) {
+               spin_lock_irqsave(&test_lock, flags);
+               un_delay(udl, ndl);
+               spin_unlock_irqrestore(&test_lock, flags);
+       }
+       preempt_enable();
+}
+
+static struct ref_scale_ops lock_irq_ops = {
+       .readsection    = ref_lock_irq_section,
+       .delaysection   = ref_lock_irq_delay_section,
+       .name           = "lock-irq"
+};
+
+// Definitions acquire-release.
+static DEFINE_PER_CPU(unsigned long, test_acqrel);
+
+static void ref_acqrel_section(const int nloops)
+{
+       unsigned long x;
+       int i;
+
+       preempt_disable();
+       for (i = nloops; i >= 0; i--) {
+               x = smp_load_acquire(this_cpu_ptr(&test_acqrel));
+               smp_store_release(this_cpu_ptr(&test_acqrel), x + 1);
+       }
+       preempt_enable();
+}
+
+static void ref_acqrel_delay_section(const int nloops, const int udl, const int ndl)
+{
+       unsigned long x;
+       int i;
+
+       preempt_disable();
+       for (i = nloops; i >= 0; i--) {
+               x = smp_load_acquire(this_cpu_ptr(&test_acqrel));
+               un_delay(udl, ndl);
+               smp_store_release(this_cpu_ptr(&test_acqrel), x + 1);
+       }
+       preempt_enable();
+}
+
+static struct ref_scale_ops acqrel_ops = {
+       .readsection    = ref_acqrel_section,
+       .delaysection   = ref_acqrel_delay_section,
+       .name           = "acqrel"
+};
+
 static void rcu_scale_one_reader(void)
 {
        if (readdelay <= 0)
@@ -653,8 +758,8 @@ ref_scale_init(void)
        long i;
        int firsterr = 0;
        static struct ref_scale_ops *scale_ops[] = {
-               &rcu_ops, &srcu_ops, &rcu_trace_ops, &rcu_tasks_ops,
-               &refcnt_ops, &rwlock_ops, &rwsem_ops,
+               &rcu_ops, &srcu_ops, &rcu_trace_ops, &rcu_tasks_ops, &refcnt_ops, &rwlock_ops,
+               &rwsem_ops, &lock_ops, &lock_irq_ops, &acqrel_ops,
        };
 
        if (!torture_init_begin(scale_type, verbose))