[PATCH v17 06/16] irq: Add KUnit test for refcounted interrupt enable/disable

Lyude Paul posted 16 patches 2 weeks, 2 days ago
[PATCH v17 06/16] irq: Add KUnit test for refcounted interrupt enable/disable
Posted by Lyude Paul 2 weeks, 2 days ago
While making changes to the refcounted interrupt patch series, at some
point on my local branch I broke something and ended up writing some kunit
tests for testing refcounted interrupts as a result. So, let's include
these tests now that we have refcounted interrupts.

Signed-off-by: Lyude Paul <lyude@redhat.com>

---
V13:
* Add missing MODULE_DESCRIPTION/MODULE_LICENSE lines
* Switch from kunit_test_suites(…) to kunit_test_suite(…)

 kernel/irq/Makefile                  |   1 +
 kernel/irq/refcount_interrupt_test.c | 109 +++++++++++++++++++++++++++
 2 files changed, 110 insertions(+)
 create mode 100644 kernel/irq/refcount_interrupt_test.c

diff --git a/kernel/irq/Makefile b/kernel/irq/Makefile
index 6ab3a40556670..7b5bb5510b110 100644
--- a/kernel/irq/Makefile
+++ b/kernel/irq/Makefile
@@ -20,3 +20,4 @@ obj-$(CONFIG_SMP) += affinity.o
 obj-$(CONFIG_GENERIC_IRQ_DEBUGFS) += debugfs.o
 obj-$(CONFIG_GENERIC_IRQ_MATRIX_ALLOCATOR) += matrix.o
 obj-$(CONFIG_IRQ_KUNIT_TEST) += irq_test.o
+obj-$(CONFIG_KUNIT) += refcount_interrupt_test.o
diff --git a/kernel/irq/refcount_interrupt_test.c b/kernel/irq/refcount_interrupt_test.c
new file mode 100644
index 0000000000000..b4f224595f261
--- /dev/null
+++ b/kernel/irq/refcount_interrupt_test.c
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * KUnit test for refcounted interrupt enable/disables.
+ */
+
+#include <kunit/test.h>
+#include <linux/interrupt_rc.h>
+
+#define TEST_IRQ_ON() KUNIT_EXPECT_FALSE(test, irqs_disabled())
+#define TEST_IRQ_OFF() KUNIT_EXPECT_TRUE(test, irqs_disabled())
+
+/* ===== Test cases ===== */
+static void test_single_irq_change(struct kunit *test)
+{
+	local_interrupt_disable();
+	TEST_IRQ_OFF();
+	local_interrupt_enable();
+}
+
+static void test_nested_irq_change(struct kunit *test)
+{
+	local_interrupt_disable();
+	TEST_IRQ_OFF();
+	local_interrupt_disable();
+	TEST_IRQ_OFF();
+	local_interrupt_disable();
+	TEST_IRQ_OFF();
+
+	local_interrupt_enable();
+	TEST_IRQ_OFF();
+	local_interrupt_enable();
+	TEST_IRQ_OFF();
+	local_interrupt_enable();
+	TEST_IRQ_ON();
+}
+
+static void test_multiple_irq_change(struct kunit *test)
+{
+	local_interrupt_disable();
+	TEST_IRQ_OFF();
+	local_interrupt_disable();
+	TEST_IRQ_OFF();
+
+	local_interrupt_enable();
+	TEST_IRQ_OFF();
+	local_interrupt_enable();
+	TEST_IRQ_ON();
+
+	local_interrupt_disable();
+	TEST_IRQ_OFF();
+	local_interrupt_enable();
+	TEST_IRQ_ON();
+}
+
+static void test_irq_save(struct kunit *test)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	TEST_IRQ_OFF();
+	local_interrupt_disable();
+	TEST_IRQ_OFF();
+	local_interrupt_enable();
+	TEST_IRQ_OFF();
+	local_irq_restore(flags);
+	TEST_IRQ_ON();
+
+	local_interrupt_disable();
+	TEST_IRQ_OFF();
+	local_irq_save(flags);
+	TEST_IRQ_OFF();
+	local_irq_restore(flags);
+	TEST_IRQ_OFF();
+	local_interrupt_enable();
+	TEST_IRQ_ON();
+}
+
+static struct kunit_case test_cases[] = {
+	KUNIT_CASE(test_single_irq_change),
+	KUNIT_CASE(test_nested_irq_change),
+	KUNIT_CASE(test_multiple_irq_change),
+	KUNIT_CASE(test_irq_save),
+	{},
+};
+
+/* (init and exit are the same */
+static int test_init(struct kunit *test)
+{
+	TEST_IRQ_ON();
+
+	return 0;
+}
+
+static void test_exit(struct kunit *test)
+{
+	TEST_IRQ_ON();
+}
+
+static struct kunit_suite refcount_interrupt_test_suite = {
+	.name = "refcount_interrupt",
+	.test_cases = test_cases,
+	.init = test_init,
+	.exit = test_exit,
+};
+
+kunit_test_suite(refcount_interrupt_test_suite);
+MODULE_AUTHOR("Lyude Paul <lyude@redhat.com>");
+MODULE_DESCRIPTION("Refcounted interrupt unit test suite");
+MODULE_LICENSE("GPL");
-- 
2.52.0

Re: [PATCH v17 06/16] irq: Add KUnit test for refcounted interrupt enable/disable
Posted by David Gow 1 week ago
On Thu, 22 Jan 2026 at 06:43, Lyude Paul <lyude@redhat.com> wrote:
>
> While making changes to the refcounted interrupt patch series, at some
> point on my local branch I broke something and ended up writing some kunit
> tests for testing refcounted interrupts as a result. So, let's include
> these tests now that we have refcounted interrupts.
>
> Signed-off-by: Lyude Paul <lyude@redhat.com>
>
> ---

Looks good to me. Not sure if it'd make sense to move this into
kernel/irq/irq_test.c alongside other IRQs, or if you like having it
separate. I'm happy either way.

Reviewed-by: David Gow <davidgow@google.com>

Cheers,
-- David


> V13:
> * Add missing MODULE_DESCRIPTION/MODULE_LICENSE lines
> * Switch from kunit_test_suites(…) to kunit_test_suite(…)
>
>  kernel/irq/Makefile                  |   1 +
>  kernel/irq/refcount_interrupt_test.c | 109 +++++++++++++++++++++++++++
>  2 files changed, 110 insertions(+)
>  create mode 100644 kernel/irq/refcount_interrupt_test.c
>
> diff --git a/kernel/irq/Makefile b/kernel/irq/Makefile
> index 6ab3a40556670..7b5bb5510b110 100644
> --- a/kernel/irq/Makefile
> +++ b/kernel/irq/Makefile
> @@ -20,3 +20,4 @@ obj-$(CONFIG_SMP) += affinity.o
>  obj-$(CONFIG_GENERIC_IRQ_DEBUGFS) += debugfs.o
>  obj-$(CONFIG_GENERIC_IRQ_MATRIX_ALLOCATOR) += matrix.o
>  obj-$(CONFIG_IRQ_KUNIT_TEST) += irq_test.o
> +obj-$(CONFIG_KUNIT) += refcount_interrupt_test.o
> diff --git a/kernel/irq/refcount_interrupt_test.c b/kernel/irq/refcount_interrupt_test.c
> new file mode 100644
> index 0000000000000..b4f224595f261
> --- /dev/null
> +++ b/kernel/irq/refcount_interrupt_test.c
> @@ -0,0 +1,109 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * KUnit test for refcounted interrupt enable/disables.
> + */
> +
> +#include <kunit/test.h>
> +#include <linux/interrupt_rc.h>
> +
> +#define TEST_IRQ_ON() KUNIT_EXPECT_FALSE(test, irqs_disabled())
> +#define TEST_IRQ_OFF() KUNIT_EXPECT_TRUE(test, irqs_disabled())
> +
> +/* ===== Test cases ===== */
> +static void test_single_irq_change(struct kunit *test)
> +{
> +       local_interrupt_disable();
> +       TEST_IRQ_OFF();
> +       local_interrupt_enable();
> +}
> +
> +static void test_nested_irq_change(struct kunit *test)
> +{
> +       local_interrupt_disable();
> +       TEST_IRQ_OFF();
> +       local_interrupt_disable();
> +       TEST_IRQ_OFF();
> +       local_interrupt_disable();
> +       TEST_IRQ_OFF();
> +
> +       local_interrupt_enable();
> +       TEST_IRQ_OFF();
> +       local_interrupt_enable();
> +       TEST_IRQ_OFF();
> +       local_interrupt_enable();
> +       TEST_IRQ_ON();
> +}
> +
> +static void test_multiple_irq_change(struct kunit *test)
> +{
> +       local_interrupt_disable();
> +       TEST_IRQ_OFF();
> +       local_interrupt_disable();
> +       TEST_IRQ_OFF();
> +
> +       local_interrupt_enable();
> +       TEST_IRQ_OFF();
> +       local_interrupt_enable();
> +       TEST_IRQ_ON();
> +
> +       local_interrupt_disable();
> +       TEST_IRQ_OFF();
> +       local_interrupt_enable();
> +       TEST_IRQ_ON();
> +}
> +
> +static void test_irq_save(struct kunit *test)
> +{
> +       unsigned long flags;
> +
> +       local_irq_save(flags);
> +       TEST_IRQ_OFF();
> +       local_interrupt_disable();
> +       TEST_IRQ_OFF();
> +       local_interrupt_enable();
> +       TEST_IRQ_OFF();
> +       local_irq_restore(flags);
> +       TEST_IRQ_ON();
> +
> +       local_interrupt_disable();
> +       TEST_IRQ_OFF();
> +       local_irq_save(flags);
> +       TEST_IRQ_OFF();
> +       local_irq_restore(flags);
> +       TEST_IRQ_OFF();
> +       local_interrupt_enable();
> +       TEST_IRQ_ON();
> +}
> +
> +static struct kunit_case test_cases[] = {
> +       KUNIT_CASE(test_single_irq_change),
> +       KUNIT_CASE(test_nested_irq_change),
> +       KUNIT_CASE(test_multiple_irq_change),
> +       KUNIT_CASE(test_irq_save),
> +       {},
> +};
> +
> +/* (init and exit are the same */
> +static int test_init(struct kunit *test)
> +{
> +       TEST_IRQ_ON();
> +
> +       return 0;
> +}
> +
> +static void test_exit(struct kunit *test)
> +{
> +       TEST_IRQ_ON();
> +}
> +
> +static struct kunit_suite refcount_interrupt_test_suite = {
> +       .name = "refcount_interrupt",
> +       .test_cases = test_cases,
> +       .init = test_init,
> +       .exit = test_exit,
> +};
> +
> +kunit_test_suite(refcount_interrupt_test_suite);
> +MODULE_AUTHOR("Lyude Paul <lyude@redhat.com>");
> +MODULE_DESCRIPTION("Refcounted interrupt unit test suite");
> +MODULE_LICENSE("GPL");
> --
> 2.52.0
>
>