1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * Simple cpumask implementation 4 * 5 * Copyright (C) 2015, Red Hat Inc, Andrew Jones <drjones@redhat.com> 6 */ 7 #ifndef _CPUMASK_H_ 8 #define _CPUMASK_H_ 9 #include <bitops.h> 10 #include <limits.h> 11 #include <asm/setup.h> 12 13 #define CPUMASK_NR_LONGS ((NR_CPUS + BITS_PER_LONG - 1) / BITS_PER_LONG) 14 15 typedef struct cpumask { 16 unsigned long bits[CPUMASK_NR_LONGS]; 17 } cpumask_t; 18 19 #define cpumask_bits(maskp) ((maskp)->bits) 20 21 static inline void cpumask_set_cpu(int cpu, cpumask_t *mask) 22 { 23 assert(cpu >= 0 && cpu < nr_cpus); 24 set_bit(cpu, cpumask_bits(mask)); 25 } 26 27 static inline void cpumask_clear_cpu(int cpu, cpumask_t *mask) 28 { 29 assert(cpu >= 0 && cpu < nr_cpus); 30 clear_bit(cpu, cpumask_bits(mask)); 31 } 32 33 static inline int cpumask_test_cpu(int cpu, const cpumask_t *mask) 34 { 35 assert(cpu >= 0 && cpu < nr_cpus); 36 return test_bit(cpu, cpumask_bits(mask)); 37 } 38 39 static inline int cpumask_test_and_set_cpu(int cpu, cpumask_t *mask) 40 { 41 assert(cpu >= 0 && cpu < nr_cpus); 42 return test_and_set_bit(cpu, cpumask_bits(mask)); 43 } 44 45 static inline int cpumask_test_and_clear_cpu(int cpu, cpumask_t *mask) 46 { 47 assert(cpu >= 0 && cpu < nr_cpus); 48 return test_and_clear_bit(cpu, cpumask_bits(mask)); 49 } 50 51 static inline void cpumask_setall(cpumask_t *mask) 52 { 53 memset(mask, 0xff, sizeof(*mask)); 54 } 55 56 static inline void cpumask_clear(cpumask_t *mask) 57 { 58 memset(mask, 0, sizeof(*mask)); 59 } 60 61 /* true if src1 is a subset of src2 */ 62 static inline bool cpumask_subset(const struct cpumask *src1, const struct cpumask *src2) 63 { 64 unsigned long lastmask = BIT_MASK(nr_cpus) - 1; 65 int i; 66 67 for (i = 0; i < BIT_WORD(nr_cpus); ++i) { 68 if (cpumask_bits(src1)[i] & ~cpumask_bits(src2)[i]) 69 return false; 70 } 71 72 return !lastmask || !((cpumask_bits(src1)[i] & ~cpumask_bits(src2)[i]) & lastmask); 73 } 74 75 static inline bool cpumask_equal(const struct cpumask *src1, const struct cpumask *src2) 76 { 77 unsigned long lastmask = BIT_MASK(nr_cpus) - 1; 78 int i; 79 80 for (i = 0; i < BIT_WORD(nr_cpus); ++i) { 81 if (cpumask_bits(src1)[i] != cpumask_bits(src2)[i]) 82 return false; 83 } 84 85 return !lastmask || (cpumask_bits(src1)[i] & lastmask) == (cpumask_bits(src2)[i] & lastmask); 86 } 87 88 static inline bool cpumask_empty(const cpumask_t *mask) 89 { 90 unsigned long lastmask = BIT_MASK(nr_cpus) - 1; 91 92 for (int i = 0; i < BIT_WORD(nr_cpus); ++i) 93 if (cpumask_bits(mask)[i]) 94 return false; 95 96 return !lastmask || !(cpumask_bits(mask)[BIT_WORD(nr_cpus)] & lastmask); 97 } 98 99 static inline bool cpumask_full(const cpumask_t *mask) 100 { 101 unsigned long lastmask = BIT_MASK(nr_cpus) - 1; 102 103 for (int i = 0; i < BIT_WORD(nr_cpus); ++i) 104 if (cpumask_bits(mask)[i] != ULONG_MAX) 105 return false; 106 107 return !lastmask || (cpumask_bits(mask)[BIT_WORD(nr_cpus)] & lastmask) == lastmask; 108 } 109 110 static inline int cpumask_weight(const cpumask_t *mask) 111 { 112 int w = 0, i; 113 114 for (i = 0; i < nr_cpus; ++i) 115 if (cpumask_test_cpu(i, mask)) 116 ++w; 117 return w; 118 } 119 120 static inline void cpumask_copy(cpumask_t *dst, const cpumask_t *src) 121 { 122 memcpy(cpumask_bits(dst), cpumask_bits(src), 123 CPUMASK_NR_LONGS * sizeof(long)); 124 } 125 126 static inline int cpumask_next(int cpu, const cpumask_t *mask) 127 { 128 while (++cpu < nr_cpus && !cpumask_test_cpu(cpu, mask)) 129 ; 130 return cpu; 131 } 132 133 #define for_each_cpu(cpu, mask) \ 134 for ((cpu) = cpumask_next(-1, mask); \ 135 (cpu) < nr_cpus; \ 136 (cpu) = cpumask_next(cpu, mask)) 137 138 extern cpumask_t cpu_present_mask; 139 extern cpumask_t cpu_online_mask; 140 extern cpumask_t cpu_idle_mask; 141 #define cpu_present(cpu) cpumask_test_cpu(cpu, &cpu_present_mask) 142 #define cpu_online(cpu) cpumask_test_cpu(cpu, &cpu_online_mask) 143 #define cpu_idle(cpu) cpumask_test_cpu(cpu, &cpu_idle_mask) 144 #define for_each_present_cpu(cpu) for_each_cpu(cpu, &cpu_present_mask) 145 #define for_each_online_cpu(cpu) for_each_cpu(cpu, &cpu_online_mask) 146 147 static inline void set_cpu_present(int cpu, bool present) 148 { 149 if (present) 150 cpumask_set_cpu(cpu, &cpu_present_mask); 151 else 152 cpumask_clear_cpu(cpu, &cpu_present_mask); 153 } 154 155 static inline void set_cpu_online(int cpu, bool online) 156 { 157 if (online) 158 cpumask_set_cpu(cpu, &cpu_online_mask); 159 else 160 cpumask_clear_cpu(cpu, &cpu_online_mask); 161 } 162 163 static inline void set_cpu_idle(int cpu, bool idle) 164 { 165 if (idle) 166 cpumask_set_cpu(cpu, &cpu_idle_mask); 167 else 168 cpumask_clear_cpu(cpu, &cpu_idle_mask); 169 } 170 171 #endif /* _CPUMASK_H_ */ 172