Commit | Line | Data |
---|---|---|
c41e8866 SV |
1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* | |
3 | * KUnit tests for cpumask. | |
4 | * | |
5 | * Author: Sander Vanheule <sander@svanheule.net> | |
6 | */ | |
7 | ||
8 | #include <kunit/test.h> | |
9 | #include <linux/cpu.h> | |
10 | #include <linux/cpumask.h> | |
11 | ||
12 | #define EXPECT_FOR_EACH_CPU_EQ(test, mask) \ | |
13 | do { \ | |
14 | const cpumask_t *m = (mask); \ | |
15 | int mask_weight = cpumask_weight(m); \ | |
16 | int cpu, iter = 0; \ | |
17 | for_each_cpu(cpu, m) \ | |
18 | iter++; \ | |
19 | KUNIT_EXPECT_EQ((test), mask_weight, iter); \ | |
20 | } while (0) | |
21 | ||
22 | #define EXPECT_FOR_EACH_CPU_NOT_EQ(test, mask) \ | |
23 | do { \ | |
24 | const cpumask_t *m = (mask); \ | |
25 | int mask_weight = cpumask_weight(m); \ | |
26 | int cpu, iter = 0; \ | |
27 | for_each_cpu_not(cpu, m) \ | |
28 | iter++; \ | |
29 | KUNIT_EXPECT_EQ((test), nr_cpu_ids - mask_weight, iter); \ | |
30 | } while (0) | |
31 | ||
32 | #define EXPECT_FOR_EACH_CPU_WRAP_EQ(test, mask) \ | |
33 | do { \ | |
34 | const cpumask_t *m = (mask); \ | |
35 | int mask_weight = cpumask_weight(m); \ | |
36 | int cpu, iter = 0; \ | |
37 | for_each_cpu_wrap(cpu, m, nr_cpu_ids / 2) \ | |
38 | iter++; \ | |
39 | KUNIT_EXPECT_EQ((test), mask_weight, iter); \ | |
40 | } while (0) | |
41 | ||
42 | #define EXPECT_FOR_EACH_CPU_BUILTIN_EQ(test, name) \ | |
43 | do { \ | |
44 | int mask_weight = num_##name##_cpus(); \ | |
45 | int cpu, iter = 0; \ | |
46 | for_each_##name##_cpu(cpu) \ | |
47 | iter++; \ | |
48 | KUNIT_EXPECT_EQ((test), mask_weight, iter); \ | |
49 | } while (0) | |
50 | ||
51 | static cpumask_t mask_empty; | |
52 | static cpumask_t mask_all; | |
53 | ||
54 | static void test_cpumask_weight(struct kunit *test) | |
55 | { | |
56 | KUNIT_EXPECT_TRUE(test, cpumask_empty(&mask_empty)); | |
57 | KUNIT_EXPECT_TRUE(test, cpumask_full(cpu_possible_mask)); | |
58 | KUNIT_EXPECT_TRUE(test, cpumask_full(&mask_all)); | |
59 | ||
60 | KUNIT_EXPECT_EQ(test, 0, cpumask_weight(&mask_empty)); | |
61 | KUNIT_EXPECT_EQ(test, nr_cpu_ids, cpumask_weight(cpu_possible_mask)); | |
62 | KUNIT_EXPECT_EQ(test, nr_cpumask_bits, cpumask_weight(&mask_all)); | |
63 | } | |
64 | ||
65 | static void test_cpumask_first(struct kunit *test) | |
66 | { | |
67 | KUNIT_EXPECT_LE(test, nr_cpu_ids, cpumask_first(&mask_empty)); | |
68 | KUNIT_EXPECT_EQ(test, 0, cpumask_first(cpu_possible_mask)); | |
69 | ||
70 | KUNIT_EXPECT_EQ(test, 0, cpumask_first_zero(&mask_empty)); | |
71 | KUNIT_EXPECT_LE(test, nr_cpu_ids, cpumask_first_zero(cpu_possible_mask)); | |
72 | } | |
73 | ||
74 | static void test_cpumask_last(struct kunit *test) | |
75 | { | |
76 | KUNIT_EXPECT_LE(test, nr_cpumask_bits, cpumask_last(&mask_empty)); | |
77 | KUNIT_EXPECT_EQ(test, nr_cpumask_bits - 1, cpumask_last(cpu_possible_mask)); | |
78 | } | |
79 | ||
80 | static void test_cpumask_next(struct kunit *test) | |
81 | { | |
82 | KUNIT_EXPECT_EQ(test, 0, cpumask_next_zero(-1, &mask_empty)); | |
83 | KUNIT_EXPECT_LE(test, nr_cpu_ids, cpumask_next_zero(-1, cpu_possible_mask)); | |
84 | ||
85 | KUNIT_EXPECT_LE(test, nr_cpu_ids, cpumask_next(-1, &mask_empty)); | |
86 | KUNIT_EXPECT_EQ(test, 0, cpumask_next(-1, cpu_possible_mask)); | |
87 | } | |
88 | ||
89 | static void test_cpumask_iterators(struct kunit *test) | |
90 | { | |
91 | EXPECT_FOR_EACH_CPU_EQ(test, &mask_empty); | |
92 | EXPECT_FOR_EACH_CPU_NOT_EQ(test, &mask_empty); | |
93 | EXPECT_FOR_EACH_CPU_WRAP_EQ(test, &mask_empty); | |
94 | ||
95 | EXPECT_FOR_EACH_CPU_EQ(test, cpu_possible_mask); | |
96 | EXPECT_FOR_EACH_CPU_NOT_EQ(test, cpu_possible_mask); | |
97 | EXPECT_FOR_EACH_CPU_WRAP_EQ(test, cpu_possible_mask); | |
98 | } | |
99 | ||
100 | static void test_cpumask_iterators_builtin(struct kunit *test) | |
101 | { | |
102 | EXPECT_FOR_EACH_CPU_BUILTIN_EQ(test, possible); | |
103 | ||
104 | /* Ensure the dynamic masks are stable while running the tests */ | |
105 | cpu_hotplug_disable(); | |
106 | ||
107 | EXPECT_FOR_EACH_CPU_BUILTIN_EQ(test, online); | |
108 | EXPECT_FOR_EACH_CPU_BUILTIN_EQ(test, present); | |
109 | ||
110 | cpu_hotplug_enable(); | |
111 | } | |
112 | ||
113 | static int test_cpumask_init(struct kunit *test) | |
114 | { | |
115 | cpumask_clear(&mask_empty); | |
116 | cpumask_setall(&mask_all); | |
117 | ||
118 | return 0; | |
119 | } | |
120 | ||
121 | static struct kunit_case test_cpumask_cases[] = { | |
122 | KUNIT_CASE(test_cpumask_weight), | |
123 | KUNIT_CASE(test_cpumask_first), | |
124 | KUNIT_CASE(test_cpumask_last), | |
125 | KUNIT_CASE(test_cpumask_next), | |
126 | KUNIT_CASE(test_cpumask_iterators), | |
127 | KUNIT_CASE(test_cpumask_iterators_builtin), | |
128 | {} | |
129 | }; | |
130 | ||
131 | static struct kunit_suite test_cpumask_suite = { | |
132 | .name = "cpumask", | |
133 | .init = test_cpumask_init, | |
134 | .test_cases = test_cpumask_cases, | |
135 | }; | |
136 | kunit_test_suite(test_cpumask_suite); | |
137 | ||
138 | MODULE_LICENSE("GPL"); |