projects/linux·blob master · refs

131 lines · 2.6 KiB

1// SPDX-License-Identifier: GPL-2.0
2/*
3 * KUnit test for refcounted interrupt enable/disables.
4 */
5
6#include <kunit/test.h>
7#include <linux/interrupt_rc.h>
8
9#define TEST_IRQ_ON() KUNIT_EXPECT_FALSE(test, irqs_disabled())
10#define TEST_IRQ_OFF() KUNIT_EXPECT_TRUE(test, irqs_disabled())
11
12/* ===== Test cases ===== */
13static void test_single_irq_change(struct kunit *test)
14{
15 local_interrupt_disable();
16 TEST_IRQ_OFF();
17 local_interrupt_enable();
18}
19
20static void test_nested_irq_change(struct kunit *test)
21{
22 local_interrupt_disable();
23 TEST_IRQ_OFF();
24 local_interrupt_disable();
25 TEST_IRQ_OFF();
26 local_interrupt_disable();
27 TEST_IRQ_OFF();
28
29 local_interrupt_enable();
30 TEST_IRQ_OFF();
31 local_interrupt_enable();
32 TEST_IRQ_OFF();
33 local_interrupt_enable();
34 TEST_IRQ_ON();
35}
36
37static void test_multiple_irq_change(struct kunit *test)
38{
39 local_interrupt_disable();
40 TEST_IRQ_OFF();
41 local_interrupt_disable();
42 TEST_IRQ_OFF();
43
44 local_interrupt_enable();
45 TEST_IRQ_OFF();
46 local_interrupt_enable();
47 TEST_IRQ_ON();
48
49 local_interrupt_disable();
50 TEST_IRQ_OFF();
51 local_interrupt_enable();
52 TEST_IRQ_ON();
53}
54
55static void test_max_nesting_irq_change(struct kunit *test)
56{
57 for (int i = 0; i < __IRQ_MASK(HARDIRQ_DISABLE_BITS); i++) {
58 local_interrupt_disable();
59 TEST_IRQ_OFF();
60 }
61
62
63 for (int i = 0; i < __IRQ_MASK(HARDIRQ_DISABLE_BITS); i++) {
64 TEST_IRQ_OFF();
65 local_interrupt_enable();
66 }
67
68 TEST_IRQ_ON();
69
70 local_interrupt_disable();
71 TEST_IRQ_OFF();
72 local_interrupt_enable();
73 TEST_IRQ_ON();
74}
75
76static void test_irq_save(struct kunit *test)
77{
78 unsigned long flags;
79
80 local_irq_save(flags);
81 TEST_IRQ_OFF();
82 local_interrupt_disable();
83 TEST_IRQ_OFF();
84 local_interrupt_enable();
85 TEST_IRQ_OFF();
86 local_irq_restore(flags);
87 TEST_IRQ_ON();
88
89 local_interrupt_disable();
90 TEST_IRQ_OFF();
91 local_irq_save(flags);
92 TEST_IRQ_OFF();
93 local_irq_restore(flags);
94 TEST_IRQ_OFF();
95 local_interrupt_enable();
96 TEST_IRQ_ON();
97}
98
99static struct kunit_case test_cases[] = {
100 KUNIT_CASE(test_single_irq_change),
101 KUNIT_CASE(test_nested_irq_change),
102 KUNIT_CASE(test_multiple_irq_change),
103 KUNIT_CASE(test_max_nesting_irq_change),
104 KUNIT_CASE(test_irq_save),
105 {},
106};
107
108/* init and exit are the same. */
109static int test_init(struct kunit *test)
110{
111 TEST_IRQ_ON();
112
113 return 0;
114}
115
116static void test_exit(struct kunit *test)
117{
118 TEST_IRQ_ON();
119}
120
121static struct kunit_suite refcount_interrupt_test_suite = {
122 .name = "refcount_interrupt",
123 .test_cases = test_cases,
124 .init = test_init,
125 .exit = test_exit,
126};
127
128kunit_test_suite(refcount_interrupt_test_suite);
129MODULE_AUTHOR("Lyude Paul <[email protected]>");
130MODULE_DESCRIPTION("Refcounted interrupt unit test suite");
131MODULE_LICENSE("GPL");