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 <asm/setup.h> 10 #include <bitops.h> 11 12 #define CPUMASK_NR_LONGS ((NR_CPUS + BITS_PER_LONG - 1) / BITS_PER_LONG) 13 14 typedef struct cpumask { 15 unsigned long bits[CPUMASK_NR_LONGS]; 16 } cpumask_t; 17 18 #define cpumask_bits(maskp) ((maskp)->bits) 19 20 static inline void cpumask_set_cpu(int cpu, cpumask_t *mask) 21 { 22 assert(cpu >= 0 && cpu < nr_cpus); 23 set_bit(cpu, cpumask_bits(mask)); 24 } 25 26 static inline void cpumask_clear_cpu(int cpu, cpumask_t *mask) 27 { 28 assert(cpu >= 0 && cpu < nr_cpus); 29 clear_bit(cpu, cpumask_bits(mask)); 30 } 31 32 static inline int cpumask_test_cpu(int cpu, const cpumask_t *mask) 33 { 34 assert(cpu >= 0 && cpu < nr_cpus); 35 return test_bit(cpu, cpumask_bits(mask)); 36 } 37 38 static inline int cpumask_test_and_set_cpu(int cpu, cpumask_t *mask) 39 { 40 assert(cpu >= 0 && cpu < nr_cpus); 41 return test_and_set_bit(cpu, cpumask_bits(mask)); 42 } 43 44 static inline int cpumask_test_and_clear_cpu(int cpu, cpumask_t *mask) 45 { 46 assert(cpu >= 0 && cpu < nr_cpus); 47 return test_and_clear_bit(cpu, cpumask_bits(mask)); 48 } 49 50 static inline void cpumask_setall(cpumask_t *mask) 51 { 52 int i; 53 for (i = 0; i < nr_cpus; i += BITS_PER_LONG) 54 cpumask_bits(mask)[BIT_WORD(i)] = ~0UL; 55 i -= BITS_PER_LONG; 56 if ((nr_cpus - i) < BITS_PER_LONG) 57 cpumask_bits(mask)[BIT_WORD(i)] = BIT_MASK(nr_cpus - i) - 1; 58 } 59 60 static inline void cpumask_clear(cpumask_t *mask) 61 { 62 int i; 63 for (i = 0; i < nr_cpus; i += BITS_PER_LONG) 64 cpumask_bits(mask)[BIT_WORD(i)] = 0UL; 65 } 66 67 static inline bool cpumask_empty(const cpumask_t *mask) 68 { 69 int i; 70 for (i = 0; i < nr_cpus; i += BITS_PER_LONG) { 71 if (i < NR_CPUS) { /* silence crazy compiler warning */ 72 if (cpumask_bits(mask)[BIT_WORD(i)] != 0UL) 73 return false; 74 } 75 } 76 return true; 77 } 78 79 static inline bool cpumask_full(const cpumask_t *mask) 80 { 81 int i; 82 for (i = 0; i < nr_cpus; i += BITS_PER_LONG) { 83 if (cpumask_bits(mask)[BIT_WORD(i)] != ~0UL) { 84 if ((nr_cpus - i) >= BITS_PER_LONG) 85 return false; 86 if (cpumask_bits(mask)[BIT_WORD(i)] 87 != BIT_MASK(nr_cpus - i) - 1) 88 return false; 89 } 90 } 91 return true; 92 } 93 94 static inline int cpumask_weight(const cpumask_t *mask) 95 { 96 int w = 0, i; 97 98 for (i = 0; i < nr_cpus; ++i) 99 if (cpumask_test_cpu(i, mask)) 100 ++w; 101 return w; 102 } 103 104 static inline void cpumask_copy(cpumask_t *dst, const cpumask_t *src) 105 { 106 memcpy(cpumask_bits(dst), cpumask_bits(src), 107 CPUMASK_NR_LONGS * sizeof(long)); 108 } 109 110 static inline int cpumask_next(int cpu, const cpumask_t *mask) 111 { 112 while (++cpu < nr_cpus && !cpumask_test_cpu(cpu, mask)) 113 ; 114 return cpu; 115 } 116 117 #define for_each_cpu(cpu, mask) \ 118 for ((cpu) = cpumask_next(-1, mask); \ 119 (cpu) < nr_cpus; \ 120 (cpu) = cpumask_next(cpu, mask)) 121 122 extern cpumask_t cpu_present_mask; 123 extern cpumask_t cpu_online_mask; 124 extern cpumask_t cpu_idle_mask; 125 #define cpu_present(cpu) cpumask_test_cpu(cpu, &cpu_present_mask) 126 #define cpu_online(cpu) cpumask_test_cpu(cpu, &cpu_online_mask) 127 #define cpu_idle(cpu) cpumask_test_cpu(cpu, &cpu_idle_mask) 128 #define for_each_present_cpu(cpu) for_each_cpu(cpu, &cpu_present_mask) 129 #define for_each_online_cpu(cpu) for_each_cpu(cpu, &cpu_online_mask) 130 131 static inline void set_cpu_present(int cpu, bool present) 132 { 133 if (present) 134 cpumask_set_cpu(cpu, &cpu_present_mask); 135 else 136 cpumask_clear_cpu(cpu, &cpu_present_mask); 137 } 138 139 static inline void set_cpu_online(int cpu, bool online) 140 { 141 if (online) 142 cpumask_set_cpu(cpu, &cpu_online_mask); 143 else 144 cpumask_clear_cpu(cpu, &cpu_online_mask); 145 } 146 147 static inline void set_cpu_idle(int cpu, bool idle) 148 { 149 if (idle) 150 cpumask_set_cpu(cpu, &cpu_idle_mask); 151 else 152 cpumask_clear_cpu(cpu, &cpu_idle_mask); 153 } 154 155 #endif /* _CPUMASK_H_ */ 156