1dfc1fec2SAndrew Jones /* SPDX-License-Identifier: GPL-2.0-only */ 2f20e2561SAndrew Jones /* 3f20e2561SAndrew Jones * Simple cpumask implementation 4f20e2561SAndrew Jones * 5f20e2561SAndrew Jones * Copyright (C) 2015, Red Hat Inc, Andrew Jones <drjones@redhat.com> 6f20e2561SAndrew Jones */ 7dfc1fec2SAndrew Jones #ifndef _CPUMASK_H_ 8dfc1fec2SAndrew Jones #define _CPUMASK_H_ 96ed97c50SPeter Feiner #include <bitops.h> 10*7213c4d6SAndrew Jones #include <limits.h> 11*7213c4d6SAndrew Jones #include <asm/setup.h> 12f20e2561SAndrew Jones 13f20e2561SAndrew Jones #define CPUMASK_NR_LONGS ((NR_CPUS + BITS_PER_LONG - 1) / BITS_PER_LONG) 14f20e2561SAndrew Jones 15f20e2561SAndrew Jones typedef struct cpumask { 16f20e2561SAndrew Jones unsigned long bits[CPUMASK_NR_LONGS]; 17f20e2561SAndrew Jones } cpumask_t; 18f20e2561SAndrew Jones 19f20e2561SAndrew Jones #define cpumask_bits(maskp) ((maskp)->bits) 20f20e2561SAndrew Jones 21f20e2561SAndrew Jones static inline void cpumask_set_cpu(int cpu, cpumask_t *mask) 22f20e2561SAndrew Jones { 23adae1302SNikos Nikoleris assert(cpu >= 0 && cpu < nr_cpus); 24f20e2561SAndrew Jones set_bit(cpu, cpumask_bits(mask)); 25f20e2561SAndrew Jones } 26f20e2561SAndrew Jones 27f20e2561SAndrew Jones static inline void cpumask_clear_cpu(int cpu, cpumask_t *mask) 28f20e2561SAndrew Jones { 29adae1302SNikos Nikoleris assert(cpu >= 0 && cpu < nr_cpus); 30f20e2561SAndrew Jones clear_bit(cpu, cpumask_bits(mask)); 31f20e2561SAndrew Jones } 32f20e2561SAndrew Jones 33f20e2561SAndrew Jones static inline int cpumask_test_cpu(int cpu, const cpumask_t *mask) 34f20e2561SAndrew Jones { 35adae1302SNikos Nikoleris assert(cpu >= 0 && cpu < nr_cpus); 36f20e2561SAndrew Jones return test_bit(cpu, cpumask_bits(mask)); 37f20e2561SAndrew Jones } 38f20e2561SAndrew Jones 39f20e2561SAndrew Jones static inline int cpumask_test_and_set_cpu(int cpu, cpumask_t *mask) 40f20e2561SAndrew Jones { 41adae1302SNikos Nikoleris assert(cpu >= 0 && cpu < nr_cpus); 42f20e2561SAndrew Jones return test_and_set_bit(cpu, cpumask_bits(mask)); 43f20e2561SAndrew Jones } 44f20e2561SAndrew Jones 45f20e2561SAndrew Jones static inline int cpumask_test_and_clear_cpu(int cpu, cpumask_t *mask) 46f20e2561SAndrew Jones { 47adae1302SNikos Nikoleris assert(cpu >= 0 && cpu < nr_cpus); 48f20e2561SAndrew Jones return test_and_clear_bit(cpu, cpumask_bits(mask)); 49f20e2561SAndrew Jones } 50f20e2561SAndrew Jones 51f20e2561SAndrew Jones static inline void cpumask_setall(cpumask_t *mask) 52f20e2561SAndrew Jones { 53*7213c4d6SAndrew Jones memset(mask, 0xff, sizeof(*mask)); 54f20e2561SAndrew Jones } 55f20e2561SAndrew Jones 56f20e2561SAndrew Jones static inline void cpumask_clear(cpumask_t *mask) 57f20e2561SAndrew Jones { 58*7213c4d6SAndrew Jones memset(mask, 0, sizeof(*mask)); 59f20e2561SAndrew Jones } 60f20e2561SAndrew Jones 61f20e2561SAndrew Jones static inline bool cpumask_empty(const cpumask_t *mask) 62f20e2561SAndrew Jones { 63*7213c4d6SAndrew Jones unsigned long lastmask = BIT_MASK(nr_cpus) - 1; 64*7213c4d6SAndrew Jones 65*7213c4d6SAndrew Jones for (int i = 0; i < BIT_WORD(nr_cpus); ++i) 66*7213c4d6SAndrew Jones if (cpumask_bits(mask)[i]) 67f20e2561SAndrew Jones return false; 68*7213c4d6SAndrew Jones 69*7213c4d6SAndrew Jones return !lastmask || !(cpumask_bits(mask)[BIT_WORD(nr_cpus)] & lastmask); 70f20e2561SAndrew Jones } 71f20e2561SAndrew Jones 72f20e2561SAndrew Jones static inline bool cpumask_full(const cpumask_t *mask) 73f20e2561SAndrew Jones { 74*7213c4d6SAndrew Jones unsigned long lastmask = BIT_MASK(nr_cpus) - 1; 75*7213c4d6SAndrew Jones 76*7213c4d6SAndrew Jones for (int i = 0; i < BIT_WORD(nr_cpus); ++i) 77*7213c4d6SAndrew Jones if (cpumask_bits(mask)[i] != ULONG_MAX) 78f20e2561SAndrew Jones return false; 79*7213c4d6SAndrew Jones 80*7213c4d6SAndrew Jones return !lastmask || (cpumask_bits(mask)[BIT_WORD(nr_cpus)] & lastmask) == lastmask; 81f20e2561SAndrew Jones } 82f20e2561SAndrew Jones 83f20e2561SAndrew Jones static inline int cpumask_weight(const cpumask_t *mask) 84f20e2561SAndrew Jones { 85f20e2561SAndrew Jones int w = 0, i; 86f20e2561SAndrew Jones 87f20e2561SAndrew Jones for (i = 0; i < nr_cpus; ++i) 88f20e2561SAndrew Jones if (cpumask_test_cpu(i, mask)) 89f20e2561SAndrew Jones ++w; 90f20e2561SAndrew Jones return w; 91f20e2561SAndrew Jones } 92f20e2561SAndrew Jones 93f20e2561SAndrew Jones static inline void cpumask_copy(cpumask_t *dst, const cpumask_t *src) 94f20e2561SAndrew Jones { 95f20e2561SAndrew Jones memcpy(cpumask_bits(dst), cpumask_bits(src), 96f20e2561SAndrew Jones CPUMASK_NR_LONGS * sizeof(long)); 97f20e2561SAndrew Jones } 98f20e2561SAndrew Jones 99f20e2561SAndrew Jones static inline int cpumask_next(int cpu, const cpumask_t *mask) 100f20e2561SAndrew Jones { 101fdab948bSNikos Nikoleris while (++cpu < nr_cpus && !cpumask_test_cpu(cpu, mask)) 102f20e2561SAndrew Jones ; 103f20e2561SAndrew Jones return cpu; 104f20e2561SAndrew Jones } 105f20e2561SAndrew Jones 106f20e2561SAndrew Jones #define for_each_cpu(cpu, mask) \ 107f20e2561SAndrew Jones for ((cpu) = cpumask_next(-1, mask); \ 108f20e2561SAndrew Jones (cpu) < nr_cpus; \ 109f20e2561SAndrew Jones (cpu) = cpumask_next(cpu, mask)) 110f20e2561SAndrew Jones 111905b0e66SAndrew Jones extern cpumask_t cpu_present_mask; 112905b0e66SAndrew Jones extern cpumask_t cpu_online_mask; 113905b0e66SAndrew Jones extern cpumask_t cpu_idle_mask; 114905b0e66SAndrew Jones #define cpu_present(cpu) cpumask_test_cpu(cpu, &cpu_present_mask) 115905b0e66SAndrew Jones #define cpu_online(cpu) cpumask_test_cpu(cpu, &cpu_online_mask) 116905b0e66SAndrew Jones #define cpu_idle(cpu) cpumask_test_cpu(cpu, &cpu_idle_mask) 117905b0e66SAndrew Jones #define for_each_present_cpu(cpu) for_each_cpu(cpu, &cpu_present_mask) 118905b0e66SAndrew Jones #define for_each_online_cpu(cpu) for_each_cpu(cpu, &cpu_online_mask) 119905b0e66SAndrew Jones 120905b0e66SAndrew Jones static inline void set_cpu_present(int cpu, bool present) 121905b0e66SAndrew Jones { 122905b0e66SAndrew Jones if (present) 123905b0e66SAndrew Jones cpumask_set_cpu(cpu, &cpu_present_mask); 124905b0e66SAndrew Jones else 125905b0e66SAndrew Jones cpumask_clear_cpu(cpu, &cpu_present_mask); 126905b0e66SAndrew Jones } 127905b0e66SAndrew Jones 128905b0e66SAndrew Jones static inline void set_cpu_online(int cpu, bool online) 129905b0e66SAndrew Jones { 130905b0e66SAndrew Jones if (online) 131905b0e66SAndrew Jones cpumask_set_cpu(cpu, &cpu_online_mask); 132905b0e66SAndrew Jones else 133905b0e66SAndrew Jones cpumask_clear_cpu(cpu, &cpu_online_mask); 134905b0e66SAndrew Jones } 135905b0e66SAndrew Jones 136905b0e66SAndrew Jones static inline void set_cpu_idle(int cpu, bool idle) 137905b0e66SAndrew Jones { 138905b0e66SAndrew Jones if (idle) 139905b0e66SAndrew Jones cpumask_set_cpu(cpu, &cpu_idle_mask); 140905b0e66SAndrew Jones else 141905b0e66SAndrew Jones cpumask_clear_cpu(cpu, &cpu_idle_mask); 142905b0e66SAndrew Jones } 143905b0e66SAndrew Jones 144dfc1fec2SAndrew Jones #endif /* _CPUMASK_H_ */ 145