The return-tail lockdep preparation must see a live hardirq context. A zero
depth must fail. Depth one and nested contexts must pass. The ordinary
preparation helper must continue to reject a live hardirq context.
Add focused boot-time lockdep cases for those four states. Skip the final
IRQ-state transition after an expected preparation failure so that each
failure remains attributable to the preparation invariant.
Assisted-by: LLM
---
lib/locking-selftest.c | 53 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c
index c3d976c801bb4..7e26b757344a4 100644
--- a/lib/locking-selftest.c
+++ b/lib/locking-selftest.c
@@ -222,6 +222,55 @@ static void init_shared_classes(void)
local_irq_enable(); \
local_bh_enable();
+static void irqtail_prepare_test_enter(unsigned int nr)
+{
+ unsigned int i;
+
+ local_irq_disable();
+ for (i = 0; i < nr; i++)
+ __irq_enter_raw();
+ trace_hardirqs_on_prepare();
+}
+
+static void irqtail_prepare_test_exit(unsigned int nr)
+{
+ unsigned int i;
+
+ for (i = 0; i < nr; i++)
+ __irq_exit_raw();
+ if (debug_locks)
+ lockdep_hardirqs_on(_THIS_IP_);
+ raw_local_irq_enable();
+}
+
+static void prepare_irqtail_0(void)
+{
+ irqtail_prepare_test_enter(0);
+ lockdep_hardirqs_on_prepare_irqtail();
+ irqtail_prepare_test_exit(0);
+}
+
+static void prepare_irqtail_1(void)
+{
+ irqtail_prepare_test_enter(1);
+ lockdep_hardirqs_on_prepare_irqtail();
+ irqtail_prepare_test_exit(1);
+}
+
+static void prepare_irqtail_2(void)
+{
+ irqtail_prepare_test_enter(2);
+ lockdep_hardirqs_on_prepare_irqtail();
+ irqtail_prepare_test_exit(2);
+}
+
+static void prepare_regular_1(void)
+{
+ irqtail_prepare_test_enter(1);
+ lockdep_hardirqs_on_prepare();
+ irqtail_prepare_test_exit(1);
+}
+
/*
* Shortcuts for lock/unlock API variants, to keep
* the testcases compact:
@@ -2934,6 +2983,10 @@ void locking_selftest(void)
DO_TESTCASE_6x2x2RW("irq read-recursion", irq_read_recursion);
DO_TESTCASE_6x2x2RW("irq read-recursion #2", irq_read_recursion2);
DO_TESTCASE_6x2x2RW("irq read-recursion #3", irq_read_recursion3);
+ DO_TESTCASE_1B("IRQ tail prepare", prepare_irqtail, 0);
+ DO_TESTCASE_1("IRQ tail prepare", prepare_irqtail, 1);
+ DO_TESTCASE_1("IRQ tail prepare", prepare_irqtail, 2);
+ DO_TESTCASE_1B("regular IRQ prepare", prepare_regular, 1);
ww_tests();
--
2.39.5 (Apple Git-154)