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_empty(const cpumask_t *mask) 76 { 77 unsigned long lastmask = BIT_MASK(nr_cpus) - 1; 78 79 for (int i = 0; i < BIT_WORD(nr_cpus); ++i) 80 if (cpumask_bits(mask)[i]) 81 return false; 82 83 return !lastmask || !(cpumask_bits(mask)[BIT_WORD(nr_cpus)] & lastmask); 84 } 85 86 static inline bool cpumask_full(const cpumask_t *mask) 87 { 88 unsigned long lastmask = BIT_MASK(nr_cpus) - 1; 89 90 for (int i = 0; i < BIT_WORD(nr_cpus); ++i) 91 if (cpumask_bits(mask)[i] != ULONG_MAX) 92 return false; 93 94 return !lastmask || (cpumask_bits(mask)[BIT_WORD(nr_cpus)] & lastmask) == lastmask; 95 } 96 97 static inline int cpumask_weight(const cpumask_t *mask) 98 { 99 int w = 0, i; 100 101 for (i = 0; i < nr_cpus; ++i) 102 if (cpumask_test_cpu(i, mask)) 103 ++w; 104 return w; 105 } 106 107 static inline void cpumask_copy(cpumask_t *dst, const cpumask_t *src) 108 { 109 memcpy(cpumask_bits(dst), cpumask_bits(src), 110 CPUMASK_NR_LONGS * sizeof(long)); 111 } 112 113 static inline int cpumask_next(int cpu, const cpumask_t *mask) 114 { 115 while (++cpu < nr_cpus && !cpumask_test_cpu(cpu, mask)) 116 ; 117 return cpu; 118 } 119 120 #define for_each_cpu(cpu, mask) \ 121 for ((cpu) = cpumask_next(-1, mask); \ 122 (cpu) < nr_cpus; \ 123 (cpu) = cpumask_next(cpu, mask)) 124 125 extern cpumask_t cpu_present_mask; 126 extern cpumask_t cpu_online_mask; 127 extern cpumask_t cpu_idle_mask; 128 #define cpu_present(cpu) cpumask_test_cpu(cpu, &cpu_present_mask) 129 #define cpu_online(cpu) cpumask_test_cpu(cpu, &cpu_online_mask) 130 #define cpu_idle(cpu) cpumask_test_cpu(cpu, &cpu_idle_mask) 131 #define for_each_present_cpu(cpu) for_each_cpu(cpu, &cpu_present_mask) 132 #define for_each_online_cpu(cpu) for_each_cpu(cpu, &cpu_online_mask) 133 134 static inline void set_cpu_present(int cpu, bool present) 135 { 136 if (present) 137 cpumask_set_cpu(cpu, &cpu_present_mask); 138 else 139 cpumask_clear_cpu(cpu, &cpu_present_mask); 140 } 141 142 static inline void set_cpu_online(int cpu, bool online) 143 { 144 if (online) 145 cpumask_set_cpu(cpu, &cpu_online_mask); 146 else 147 cpumask_clear_cpu(cpu, &cpu_online_mask); 148 } 149 150 static inline void set_cpu_idle(int cpu, bool idle) 151 { 152 if (idle) 153 cpumask_set_cpu(cpu, &cpu_idle_mask); 154 else 155 cpumask_clear_cpu(cpu, &cpu_idle_mask); 156 } 157 158 #endif /* _CPUMASK_H_ */ 159