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 MASK_MSG(m) \ 13 "%s contains %sCPUs %*pbl", #m, (cpumask_weight(m) ? "" : "no "), \ 14 nr_cpumask_bits, cpumask_bits(m) 15 16 #define EXPECT_FOR_EACH_CPU_EQ(test, mask) \ 17 do { \ 18 const cpumask_t *m = (mask); \ 19 int mask_weight = cpumask_weight(m); \ 20 int cpu, iter = 0; \ 21 for_each_cpu(cpu, m) \ 22 iter++; \ 23 KUNIT_EXPECT_EQ_MSG((test), mask_weight, iter, MASK_MSG(mask)); \ 24 } while (0) 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 36 #define EXPECT_FOR_EACH_CPU_OP_EQ(test, op, mask1, mask2) \ 37 do { \ 38 const cpumask_t *m1 = (mask1); \ 39 const cpumask_t *m2 = (mask2); \ 40 int weight; \ 41 int cpu, iter = 0; \ 42 cpumask_##op(&mask_tmp, m1, m2); \ 43 weight = cpumask_weight(&mask_tmp); \ 44 for_each_cpu_##op(cpu, mask1, mask2) \ 45 iter++; \ 46 KUNIT_EXPECT_EQ((test), weight, iter); \ 47 } while (0) 48 49 #define EXPECT_FOR_EACH_CPU_WRAP_EQ(test, mask) \ 50 do { \ 51 const cpumask_t *m = (mask); \ 52 int mask_weight = cpumask_weight(m); \ 53 int cpu, iter = 0; \ 54 for_each_cpu_wrap(cpu, m, nr_cpu_ids / 2) \ 55 iter++; \ 56 KUNIT_EXPECT_EQ_MSG((test), mask_weight, iter, MASK_MSG(mask)); \ 57 } while (0) 58 59 #define EXPECT_FOR_EACH_CPU_BUILTIN_EQ(test, name) \ 60 do { \ 61 int mask_weight = num_##name##_cpus(); \ 62 int cpu, iter = 0; \ 63 for_each_##name##_cpu(cpu) \ 64 iter++; \ 65 KUNIT_EXPECT_EQ_MSG((test), mask_weight, iter, MASK_MSG(cpu_##name##_mask)); \ 66 } while (0) 67 68 static cpumask_t mask_empty; 69 static cpumask_t mask_all; 70 static cpumask_t mask_tmp; 71 72 static void test_cpumask_weight(struct kunit *test) 73 { 74 KUNIT_EXPECT_TRUE_MSG(test, cpumask_empty(&mask_empty), MASK_MSG(&mask_empty)); 75 KUNIT_EXPECT_TRUE_MSG(test, cpumask_full(&mask_all), MASK_MSG(&mask_all)); 76 77 KUNIT_EXPECT_EQ_MSG(test, 0, cpumask_weight(&mask_empty), MASK_MSG(&mask_empty)); 78 KUNIT_EXPECT_EQ_MSG(test, nr_cpu_ids, cpumask_weight(cpu_possible_mask), 79 MASK_MSG(cpu_possible_mask)); 80 KUNIT_EXPECT_EQ_MSG(test, nr_cpumask_bits, cpumask_weight(&mask_all), MASK_MSG(&mask_all)); 81 } 82 83 static void test_cpumask_first(struct kunit *test) 84 { 85 KUNIT_EXPECT_LE_MSG(test, nr_cpu_ids, cpumask_first(&mask_empty), MASK_MSG(&mask_empty)); 86 KUNIT_EXPECT_EQ_MSG(test, 0, cpumask_first(cpu_possible_mask), MASK_MSG(cpu_possible_mask)); 87 88 KUNIT_EXPECT_EQ_MSG(test, 0, cpumask_first_zero(&mask_empty), MASK_MSG(&mask_empty)); 89 KUNIT_EXPECT_LE_MSG(test, nr_cpu_ids, cpumask_first_zero(cpu_possible_mask), 90 MASK_MSG(cpu_possible_mask)); 91 } 92 93 static void test_cpumask_last(struct kunit *test) 94 { 95 KUNIT_EXPECT_LE_MSG(test, nr_cpumask_bits, cpumask_last(&mask_empty), 96 MASK_MSG(&mask_empty)); 97 KUNIT_EXPECT_EQ_MSG(test, nr_cpu_ids - 1, cpumask_last(cpu_possible_mask), 98 MASK_MSG(cpu_possible_mask)); 99 } 100 101 static void test_cpumask_next(struct kunit *test) 102 { 103 KUNIT_EXPECT_EQ_MSG(test, 0, cpumask_next_zero(-1, &mask_empty), MASK_MSG(&mask_empty)); 104 KUNIT_EXPECT_LE_MSG(test, nr_cpu_ids, cpumask_next_zero(-1, cpu_possible_mask), 105 MASK_MSG(cpu_possible_mask)); 106 107 KUNIT_EXPECT_LE_MSG(test, nr_cpu_ids, cpumask_next(-1, &mask_empty), 108 MASK_MSG(&mask_empty)); 109 KUNIT_EXPECT_EQ_MSG(test, 0, cpumask_next(-1, cpu_possible_mask), 110 MASK_MSG(cpu_possible_mask)); 111 } 112 113 static void test_cpumask_iterators(struct kunit *test) 114 { 115 EXPECT_FOR_EACH_CPU_EQ(test, &mask_empty); 116 EXPECT_FOR_EACH_CPU_NOT_EQ(test, &mask_empty); 117 EXPECT_FOR_EACH_CPU_WRAP_EQ(test, &mask_empty); 118 EXPECT_FOR_EACH_CPU_OP_EQ(test, and, &mask_empty, &mask_empty); 119 EXPECT_FOR_EACH_CPU_OP_EQ(test, and, cpu_possible_mask, &mask_empty); 120 EXPECT_FOR_EACH_CPU_OP_EQ(test, andnot, &mask_empty, &mask_empty); 121 122 EXPECT_FOR_EACH_CPU_EQ(test, cpu_possible_mask); 123 EXPECT_FOR_EACH_CPU_NOT_EQ(test, cpu_possible_mask); 124 EXPECT_FOR_EACH_CPU_WRAP_EQ(test, cpu_possible_mask); 125 EXPECT_FOR_EACH_CPU_OP_EQ(test, and, cpu_possible_mask, cpu_possible_mask); 126 EXPECT_FOR_EACH_CPU_OP_EQ(test, andnot, cpu_possible_mask, &mask_empty); 127 } 128 129 static void test_cpumask_iterators_builtin(struct kunit *test) 130 { 131 EXPECT_FOR_EACH_CPU_BUILTIN_EQ(test, possible); 132 133 /* Ensure the dynamic masks are stable while running the tests */ 134 cpu_hotplug_disable(); 135 136 EXPECT_FOR_EACH_CPU_BUILTIN_EQ(test, online); 137 EXPECT_FOR_EACH_CPU_BUILTIN_EQ(test, present); 138 139 cpu_hotplug_enable(); 140 } 141 142 static int test_cpumask_init(struct kunit *test) 143 { 144 cpumask_clear(&mask_empty); 145 cpumask_setall(&mask_all); 146 147 return 0; 148 } 149 150 static struct kunit_case test_cpumask_cases[] = { 151 KUNIT_CASE(test_cpumask_weight), 152 KUNIT_CASE(test_cpumask_first), 153 KUNIT_CASE(test_cpumask_last), 154 KUNIT_CASE(test_cpumask_next), 155 KUNIT_CASE(test_cpumask_iterators), 156 KUNIT_CASE(test_cpumask_iterators_builtin), 157 {} 158 }; 159 160 static struct kunit_suite test_cpumask_suite = { 161 .name = "cpumask", 162 .init = test_cpumask_init, 163 .test_cases = test_cpumask_cases, 164 }; 165 kunit_test_suite(test_cpumask_suite); 166 167 MODULE_LICENSE("GPL"); 168