1 // SPDX-License-Identifier: GPL-2.0-only 1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 2 /* 3 * KUnit tests for cpumask. 3 * KUnit tests for cpumask. 4 * 4 * 5 * Author: Sander Vanheule <sander@svanheule.n 5 * Author: Sander Vanheule <sander@svanheule.net> 6 */ 6 */ 7 7 8 #include <kunit/test.h> 8 #include <kunit/test.h> 9 #include <linux/cpu.h> 9 #include <linux/cpu.h> 10 #include <linux/cpumask.h> 10 #include <linux/cpumask.h> 11 11 12 #define MASK_MSG(m) \ 12 #define MASK_MSG(m) \ 13 "%s contains %sCPUs %*pbl", #m, (cpuma 13 "%s contains %sCPUs %*pbl", #m, (cpumask_weight(m) ? "" : "no "), \ 14 nr_cpumask_bits, cpumask_bits(m) 14 nr_cpumask_bits, cpumask_bits(m) 15 15 16 #define EXPECT_FOR_EACH_CPU_EQ(test, mask) 16 #define EXPECT_FOR_EACH_CPU_EQ(test, mask) \ 17 do { 17 do { \ 18 const cpumask_t *m = (mask); 18 const cpumask_t *m = (mask); \ 19 int mask_weight = cpumask_weig 19 int mask_weight = cpumask_weight(m); \ 20 int cpu, iter = 0; 20 int cpu, iter = 0; \ 21 for_each_cpu(cpu, m) 21 for_each_cpu(cpu, m) \ 22 iter++; 22 iter++; \ 23 KUNIT_EXPECT_EQ_MSG((test), ma 23 KUNIT_EXPECT_EQ_MSG((test), mask_weight, iter, MASK_MSG(mask)); \ 24 } while (0) 24 } while (0) 25 25 >> 26 #define EXPECT_FOR_EACH_CPU_NOT_EQ(test, mask) \ >> 27 do { \ >> 28 const cpumask_t *m = (mask); \ >> 29 int mask_weight = cpumask_weight(m); \ >> 30 int cpu, iter = 0; \ >> 31 for_each_cpu_not(cpu, m) \ >> 32 iter++; \ >> 33 KUNIT_EXPECT_EQ_MSG((test), nr_cpu_ids - mask_weight, iter, MASK_MSG(mask)); \ >> 34 } while (0) >> 35 26 #define EXPECT_FOR_EACH_CPU_OP_EQ(test, op, ma 36 #define EXPECT_FOR_EACH_CPU_OP_EQ(test, op, mask1, mask2) \ 27 do { 37 do { \ 28 const cpumask_t *m1 = (mask1); 38 const cpumask_t *m1 = (mask1); \ 29 const cpumask_t *m2 = (mask2); 39 const cpumask_t *m2 = (mask2); \ 30 int weight; 40 int weight; \ 31 int cpu, iter = 0; 41 int cpu, iter = 0; \ 32 cpumask_##op(&mask_tmp, m1, m2 42 cpumask_##op(&mask_tmp, m1, m2); \ 33 weight = cpumask_weight(&mask_ 43 weight = cpumask_weight(&mask_tmp); \ 34 for_each_cpu_##op(cpu, mask1, 44 for_each_cpu_##op(cpu, mask1, mask2) \ 35 iter++; 45 iter++; \ 36 KUNIT_EXPECT_EQ((test), weight 46 KUNIT_EXPECT_EQ((test), weight, iter); \ 37 } while (0) 47 } while (0) 38 48 39 #define EXPECT_FOR_EACH_CPU_WRAP_EQ(test, mask 49 #define EXPECT_FOR_EACH_CPU_WRAP_EQ(test, mask) \ 40 do { 50 do { \ 41 const cpumask_t *m = (mask); 51 const cpumask_t *m = (mask); \ 42 int mask_weight = cpumask_weig 52 int mask_weight = cpumask_weight(m); \ 43 int cpu, iter = 0; 53 int cpu, iter = 0; \ 44 for_each_cpu_wrap(cpu, m, nr_c 54 for_each_cpu_wrap(cpu, m, nr_cpu_ids / 2) \ 45 iter++; 55 iter++; \ 46 KUNIT_EXPECT_EQ_MSG((test), ma 56 KUNIT_EXPECT_EQ_MSG((test), mask_weight, iter, MASK_MSG(mask)); \ 47 } while (0) 57 } while (0) 48 58 49 #define EXPECT_FOR_EACH_CPU_BUILTIN_EQ(test, n 59 #define EXPECT_FOR_EACH_CPU_BUILTIN_EQ(test, name) \ 50 do { 60 do { \ 51 int mask_weight = num_##name## 61 int mask_weight = num_##name##_cpus(); \ 52 int cpu, iter = 0; 62 int cpu, iter = 0; \ 53 for_each_##name##_cpu(cpu) 63 for_each_##name##_cpu(cpu) \ 54 iter++; 64 iter++; \ 55 KUNIT_EXPECT_EQ_MSG((test), ma 65 KUNIT_EXPECT_EQ_MSG((test), mask_weight, iter, MASK_MSG(cpu_##name##_mask)); \ 56 } while (0) 66 } while (0) 57 67 58 static cpumask_t mask_empty; 68 static cpumask_t mask_empty; 59 static cpumask_t mask_all; 69 static cpumask_t mask_all; 60 static cpumask_t mask_tmp; 70 static cpumask_t mask_tmp; 61 71 62 static void test_cpumask_weight(struct kunit * 72 static void test_cpumask_weight(struct kunit *test) 63 { 73 { 64 KUNIT_EXPECT_TRUE_MSG(test, cpumask_em 74 KUNIT_EXPECT_TRUE_MSG(test, cpumask_empty(&mask_empty), MASK_MSG(&mask_empty)); 65 KUNIT_EXPECT_TRUE_MSG(test, cpumask_fu 75 KUNIT_EXPECT_TRUE_MSG(test, cpumask_full(&mask_all), MASK_MSG(&mask_all)); 66 76 67 KUNIT_EXPECT_EQ_MSG(test, 0, cpumask_w 77 KUNIT_EXPECT_EQ_MSG(test, 0, cpumask_weight(&mask_empty), MASK_MSG(&mask_empty)); 68 KUNIT_EXPECT_EQ_MSG(test, nr_cpu_ids, 78 KUNIT_EXPECT_EQ_MSG(test, nr_cpu_ids, cpumask_weight(cpu_possible_mask), 69 MASK_MSG(cpu_possi 79 MASK_MSG(cpu_possible_mask)); 70 KUNIT_EXPECT_EQ_MSG(test, nr_cpu_ids, !! 80 KUNIT_EXPECT_EQ_MSG(test, nr_cpumask_bits, cpumask_weight(&mask_all), MASK_MSG(&mask_all)); 71 } 81 } 72 82 73 static void test_cpumask_first(struct kunit *t 83 static void test_cpumask_first(struct kunit *test) 74 { 84 { 75 KUNIT_EXPECT_LE_MSG(test, nr_cpu_ids, 85 KUNIT_EXPECT_LE_MSG(test, nr_cpu_ids, cpumask_first(&mask_empty), MASK_MSG(&mask_empty)); 76 KUNIT_EXPECT_EQ_MSG(test, 0, cpumask_f 86 KUNIT_EXPECT_EQ_MSG(test, 0, cpumask_first(cpu_possible_mask), MASK_MSG(cpu_possible_mask)); 77 87 78 KUNIT_EXPECT_EQ_MSG(test, 0, cpumask_f 88 KUNIT_EXPECT_EQ_MSG(test, 0, cpumask_first_zero(&mask_empty), MASK_MSG(&mask_empty)); 79 KUNIT_EXPECT_LE_MSG(test, nr_cpu_ids, 89 KUNIT_EXPECT_LE_MSG(test, nr_cpu_ids, cpumask_first_zero(cpu_possible_mask), 80 MASK_MSG(cpu_possi 90 MASK_MSG(cpu_possible_mask)); 81 } 91 } 82 92 83 static void test_cpumask_last(struct kunit *te 93 static void test_cpumask_last(struct kunit *test) 84 { 94 { 85 KUNIT_EXPECT_LE_MSG(test, nr_cpumask_b 95 KUNIT_EXPECT_LE_MSG(test, nr_cpumask_bits, cpumask_last(&mask_empty), 86 MASK_MSG(&mask_emp 96 MASK_MSG(&mask_empty)); 87 KUNIT_EXPECT_EQ_MSG(test, nr_cpu_ids - 97 KUNIT_EXPECT_EQ_MSG(test, nr_cpu_ids - 1, cpumask_last(cpu_possible_mask), 88 MASK_MSG(cpu_possi 98 MASK_MSG(cpu_possible_mask)); 89 } 99 } 90 100 91 static void test_cpumask_next(struct kunit *te 101 static void test_cpumask_next(struct kunit *test) 92 { 102 { 93 KUNIT_EXPECT_EQ_MSG(test, 0, cpumask_n 103 KUNIT_EXPECT_EQ_MSG(test, 0, cpumask_next_zero(-1, &mask_empty), MASK_MSG(&mask_empty)); 94 KUNIT_EXPECT_LE_MSG(test, nr_cpu_ids, 104 KUNIT_EXPECT_LE_MSG(test, nr_cpu_ids, cpumask_next_zero(-1, cpu_possible_mask), 95 MASK_MSG(cpu_possi 105 MASK_MSG(cpu_possible_mask)); 96 106 97 KUNIT_EXPECT_LE_MSG(test, nr_cpu_ids, 107 KUNIT_EXPECT_LE_MSG(test, nr_cpu_ids, cpumask_next(-1, &mask_empty), 98 MASK_MSG(&mask_emp 108 MASK_MSG(&mask_empty)); 99 KUNIT_EXPECT_EQ_MSG(test, 0, cpumask_n 109 KUNIT_EXPECT_EQ_MSG(test, 0, cpumask_next(-1, cpu_possible_mask), 100 MASK_MSG(cpu_possi 110 MASK_MSG(cpu_possible_mask)); 101 } 111 } 102 112 103 static void test_cpumask_iterators(struct kuni 113 static void test_cpumask_iterators(struct kunit *test) 104 { 114 { 105 EXPECT_FOR_EACH_CPU_EQ(test, &mask_emp 115 EXPECT_FOR_EACH_CPU_EQ(test, &mask_empty); >> 116 EXPECT_FOR_EACH_CPU_NOT_EQ(test, &mask_empty); 106 EXPECT_FOR_EACH_CPU_WRAP_EQ(test, &mas 117 EXPECT_FOR_EACH_CPU_WRAP_EQ(test, &mask_empty); 107 EXPECT_FOR_EACH_CPU_OP_EQ(test, and, & 118 EXPECT_FOR_EACH_CPU_OP_EQ(test, and, &mask_empty, &mask_empty); 108 EXPECT_FOR_EACH_CPU_OP_EQ(test, and, c 119 EXPECT_FOR_EACH_CPU_OP_EQ(test, and, cpu_possible_mask, &mask_empty); 109 EXPECT_FOR_EACH_CPU_OP_EQ(test, andnot 120 EXPECT_FOR_EACH_CPU_OP_EQ(test, andnot, &mask_empty, &mask_empty); 110 121 111 EXPECT_FOR_EACH_CPU_EQ(test, cpu_possi 122 EXPECT_FOR_EACH_CPU_EQ(test, cpu_possible_mask); >> 123 EXPECT_FOR_EACH_CPU_NOT_EQ(test, cpu_possible_mask); 112 EXPECT_FOR_EACH_CPU_WRAP_EQ(test, cpu_ 124 EXPECT_FOR_EACH_CPU_WRAP_EQ(test, cpu_possible_mask); 113 EXPECT_FOR_EACH_CPU_OP_EQ(test, and, c 125 EXPECT_FOR_EACH_CPU_OP_EQ(test, and, cpu_possible_mask, cpu_possible_mask); 114 EXPECT_FOR_EACH_CPU_OP_EQ(test, andnot 126 EXPECT_FOR_EACH_CPU_OP_EQ(test, andnot, cpu_possible_mask, &mask_empty); 115 } 127 } 116 128 117 static void test_cpumask_iterators_builtin(str 129 static void test_cpumask_iterators_builtin(struct kunit *test) 118 { 130 { 119 EXPECT_FOR_EACH_CPU_BUILTIN_EQ(test, p 131 EXPECT_FOR_EACH_CPU_BUILTIN_EQ(test, possible); 120 132 121 /* Ensure the dynamic masks are stable 133 /* Ensure the dynamic masks are stable while running the tests */ 122 cpu_hotplug_disable(); 134 cpu_hotplug_disable(); 123 135 124 EXPECT_FOR_EACH_CPU_BUILTIN_EQ(test, o 136 EXPECT_FOR_EACH_CPU_BUILTIN_EQ(test, online); 125 EXPECT_FOR_EACH_CPU_BUILTIN_EQ(test, p 137 EXPECT_FOR_EACH_CPU_BUILTIN_EQ(test, present); 126 138 127 cpu_hotplug_enable(); 139 cpu_hotplug_enable(); 128 } 140 } 129 141 130 static int test_cpumask_init(struct kunit *tes 142 static int test_cpumask_init(struct kunit *test) 131 { 143 { 132 cpumask_clear(&mask_empty); 144 cpumask_clear(&mask_empty); 133 cpumask_setall(&mask_all); 145 cpumask_setall(&mask_all); 134 146 135 return 0; 147 return 0; 136 } 148 } 137 149 138 static struct kunit_case test_cpumask_cases[] 150 static struct kunit_case test_cpumask_cases[] = { 139 KUNIT_CASE(test_cpumask_weight), 151 KUNIT_CASE(test_cpumask_weight), 140 KUNIT_CASE(test_cpumask_first), 152 KUNIT_CASE(test_cpumask_first), 141 KUNIT_CASE(test_cpumask_last), 153 KUNIT_CASE(test_cpumask_last), 142 KUNIT_CASE(test_cpumask_next), 154 KUNIT_CASE(test_cpumask_next), 143 KUNIT_CASE(test_cpumask_iterators), 155 KUNIT_CASE(test_cpumask_iterators), 144 KUNIT_CASE(test_cpumask_iterators_buil 156 KUNIT_CASE(test_cpumask_iterators_builtin), 145 {} 157 {} 146 }; 158 }; 147 159 148 static struct kunit_suite test_cpumask_suite = 160 static struct kunit_suite test_cpumask_suite = { 149 .name = "cpumask", 161 .name = "cpumask", 150 .init = test_cpumask_init, 162 .init = test_cpumask_init, 151 .test_cases = test_cpumask_cases, 163 .test_cases = test_cpumask_cases, 152 }; 164 }; 153 kunit_test_suite(test_cpumask_suite); 165 kunit_test_suite(test_cpumask_suite); 154 166 155 MODULE_DESCRIPTION("KUnit tests for cpumask"); << 156 MODULE_LICENSE("GPL"); 167 MODULE_LICENSE("GPL"); 157 168
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.