rust-for-linux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] refscale: Add tests for local_irq_disable() vs local_interrupt_disable()
@ 2025-06-19 17:53 Joel Fernandes
  2025-06-20  4:46 ` kernel test robot
  0 siblings, 1 reply; 2+ messages in thread
From: Joel Fernandes @ 2025-06-19 17:53 UTC (permalink / raw)
  To: linux-kernel, Davidlohr Bueso, Paul E. McKenney, Josh Triplett,
	Frederic Weisbecker, Neeraj Upadhyay, Joel Fernandes, Boqun Feng,
	Uladzislau Rezki, Steven Rostedt, Mathieu Desnoyers,
	Lai Jiangshan, Zqiang, Miguel Ojeda, Alex Gaynor, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich
  Cc: Lyude Paul, rcu, Joel Fernandes, rust-for-linux

Add two new refscale test cases to compare the performance of
traditional local_irq_disable()/local_irq_enable() with the newer
local_interrupt_disable()/local_interrupt_enable() APIs.

The local_interrupt_disable()/local_interrupt_enable() APIs are
introduced to provide a Rust-compatible interface for interrupt
control, as mentioned in:
https://lore.kernel.org/all/20240527222254.565881-1-lyude@redhat.com/

The 2 new tests are "local_interrupt" for the new API and "local_irq" test
for the traditional one. This allows direct performance comparison
between the two approaches.

Test results on x86 with 4 readers, 5 runs, 10000 loops:

local_irq (traditional API):
  Run 1: 1.306 ns
  Run 2: 1.306 ns
  Run 3: 1.305 ns
  Run 4: 1.307 ns
  Run 5: 1.085 ns
  Average: ~1.26 ns per operation

local_interrupt (new API):
  Run 1: 4.594 ns
  Run 2: 4.201 ns
  Run 3: 4.428 ns
  Run 4: 4.905 ns
  Run 5: 4.566 ns
  Average: ~4.54 ns per operation

The results show higher overhead with local_interrupt_disable()/enable()
possibly coming from the additional state tracking.

To run the module, modprobe refscale scale_type=local_irq (or local_interrupt).

Cc: Lyude Paul <lyude@redhat.com>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: rcu@vger.kernel.org
Signed-off-by: Joel Fernandes (Google) <joel@joelfernandes.org>
---
 kernel/rcu/refscale.c | 73 ++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 69 insertions(+), 4 deletions(-)

diff --git a/kernel/rcu/refscale.c b/kernel/rcu/refscale.c
index f11a7c2af778..ac6e2391d672 100644
--- a/kernel/rcu/refscale.c
+++ b/kernel/rcu/refscale.c
@@ -71,7 +71,7 @@ MODULE_AUTHOR("Joel Fernandes (Google) <joel@joelfernandes.org>");
 
 static char *scale_type = "rcu";
 module_param(scale_type, charp, 0444);
-MODULE_PARM_DESC(scale_type, "Type of test (rcu, srcu, refcnt, rwsem, rwlock.");
+MODULE_PARM_DESC(scale_type, "Type of test (rcu, srcu, refcnt, rwsem, rwlock, local_interrupt, local_irq.");
 
 torture_param(int, verbose, 0, "Enable verbose debugging printk()s");
 torture_param(int, verbose_batched, 0, "Batch verbose debugging printk()s");
@@ -524,6 +524,62 @@ static const struct ref_scale_ops lock_irq_ops = {
 	.name		= "lock-irq"
 };
 
+// IRQ disable/enable tests using interrupt_disable/enable.
+static void ref_local_interrupt_section(const int nloops)
+{
+	int i;
+
+	for (i = nloops; i >= 0; i--) {
+		local_interrupt_disable();
+		local_interrupt_enable();
+	}
+}
+
+static void ref_local_interrupt_delay_section(const int nloops, const int udl, const int ndl)
+{
+	int i;
+
+	for (i = nloops; i >= 0; i--) {
+		local_interrupt_disable();
+		un_delay(udl, ndl);
+		local_interrupt_enable();
+	}
+}
+
+static const struct ref_scale_ops local_interrupt_ops = {
+	.readsection	= ref_local_interrupt_section,
+	.delaysection	= ref_local_interrupt_delay_section,
+	.name		= "local_interrupt"
+};
+
+// IRQ disable/enable tests using local_irq_disable/enable.
+static void ref_local_irq_section(const int nloops)
+{
+	int i;
+
+	for (i = nloops; i >= 0; i--) {
+		local_irq_disable();
+		local_irq_enable();
+	}
+}
+
+static void ref_local_irq_delay_section(const int nloops, const int udl, const int ndl)
+{
+	int i;
+
+	for (i = nloops; i >= 0; i--) {
+		local_irq_disable();
+		un_delay(udl, ndl);
+		local_irq_enable();
+	}
+}
+
+static const struct ref_scale_ops local_irq_ops = {
+	.readsection	= ref_local_irq_section,
+	.delaysection	= ref_local_irq_delay_section,
+	.name		= "local_irq"
+};
+
 // Definitions acquire-release.
 static DEFINE_PER_CPU(unsigned long, test_acqrel);
 
@@ -956,13 +1012,22 @@ ref_scale_reader(void *arg)
 			rcu_scale_one_reader();
 	// Also keep interrupts disabled.  This also has the effect
 	// of preventing entries into slow path for rcu_read_unlock().
-	local_irq_save(flags);
+	// Exception: for IRQ ops, use preempt_disable instead since we need
+	// to test actual IRQ disable/enable performance.
+	if (cur_ops == &local_interrupt_ops || cur_ops == &local_irq_ops)
+		preempt_disable();
+	else
+		local_irq_save(flags);
 	start = ktime_get_mono_fast_ns();
 
 	rcu_scale_one_reader();
 
 	duration = ktime_get_mono_fast_ns() - start;
-	local_irq_restore(flags);
+
+	if (cur_ops == &local_interrupt_ops || cur_ops == &local_irq_ops)
+		preempt_enable();
+	else
+		local_irq_restore(flags);
 
 	rt->last_duration_ns = WARN_ON_ONCE(duration < 0) ? 0 : duration;
 	// To reduce runtime-skew noise, do maintain-load invocations until
@@ -1194,7 +1259,7 @@ ref_scale_init(void)
 	int firsterr = 0;
 	static const struct ref_scale_ops *scale_ops[] = {
 		&rcu_ops, &srcu_ops, &srcu_fast_ops, &srcu_lite_ops, RCU_TRACE_OPS RCU_TASKS_OPS
-		&refcnt_ops, &rwlock_ops, &rwsem_ops, &lock_ops, &lock_irq_ops,
+		&refcnt_ops, &rwlock_ops, &rwsem_ops, &lock_ops, &lock_irq_ops, &local_interrupt_ops, &local_irq_ops,
 		&acqrel_ops, &sched_clock_ops, &clock_ops, &jiffies_ops,
 		&typesafe_ref_ops, &typesafe_lock_ops, &typesafe_seqlock_ops,
 	};
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH v2] refscale: Add tests for local_irq_disable() vs local_interrupt_disable()
  2025-06-19 17:53 [PATCH v2] refscale: Add tests for local_irq_disable() vs local_interrupt_disable() Joel Fernandes
@ 2025-06-20  4:46 ` kernel test robot
  0 siblings, 0 replies; 2+ messages in thread
From: kernel test robot @ 2025-06-20  4:46 UTC (permalink / raw)
  To: Joel Fernandes, linux-kernel, Davidlohr Bueso, Paul E. McKenney,
	Josh Triplett, Frederic Weisbecker, Neeraj Upadhyay, Boqun Feng,
	Uladzislau Rezki, Steven Rostedt, Mathieu Desnoyers,
	Lai Jiangshan, Zqiang, Miguel Ojeda, Alex Gaynor, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich
  Cc: oe-kbuild-all, Lyude Paul, rcu, rust-for-linux

Hi Joel,

kernel test robot noticed the following build errors:

[auto build test ERROR on rcu/rcu/dev]
[also build test ERROR on linus/master v6.16-rc2 next-20250619]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Joel-Fernandes/refscale-Add-tests-for-local_irq_disable-vs-local_interrupt_disable/20250620-015541
base:   https://git.kernel.org/pub/scm/linux/kernel/git/rcu/linux.git rcu/dev
patch link:    https://lore.kernel.org/r/20250619175335.2905836-1-joelagnelf%40nvidia.com
patch subject: [PATCH v2] refscale: Add tests for local_irq_disable() vs local_interrupt_disable()
config: x86_64-buildonly-randconfig-004-20250620 (https://download.01.org/0day-ci/archive/20250620/202506201210.X8F6SB7c-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250620/202506201210.X8F6SB7c-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202506201210.X8F6SB7c-lkp@intel.com/

All errors (new ones prefixed by >>):

   kernel/rcu/refscale.c: In function 'ref_local_interrupt_section':
>> kernel/rcu/refscale.c:533:17: error: implicit declaration of function 'local_interrupt_disable'; did you mean 'local_irq_disable'? [-Werror=implicit-function-declaration]
     533 |                 local_interrupt_disable();
         |                 ^~~~~~~~~~~~~~~~~~~~~~~
         |                 local_irq_disable
>> kernel/rcu/refscale.c:534:17: error: implicit declaration of function 'local_interrupt_enable'; did you mean 'local_irq_enable'? [-Werror=implicit-function-declaration]
     534 |                 local_interrupt_enable();
         |                 ^~~~~~~~~~~~~~~~~~~~~~
         |                 local_irq_enable
   cc1: some warnings being treated as errors


vim +533 kernel/rcu/refscale.c

   526	
   527	// IRQ disable/enable tests using interrupt_disable/enable.
   528	static void ref_local_interrupt_section(const int nloops)
   529	{
   530		int i;
   531	
   532		for (i = nloops; i >= 0; i--) {
 > 533			local_interrupt_disable();
 > 534			local_interrupt_enable();
   535		}
   536	}
   537	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2025-06-20  4:46 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-19 17:53 [PATCH v2] refscale: Add tests for local_irq_disable() vs local_interrupt_disable() Joel Fernandes
2025-06-20  4:46 ` kernel test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).