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