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