1*dfc1fec2SAndrew 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 */ 7*dfc1fec2SAndrew Jones #ifndef _CPUMASK_H_ 8*dfc1fec2SAndrew Jones #define _CPUMASK_H_ 9f20e2561SAndrew Jones #include <asm/setup.h> 106ed97c50SPeter Feiner #include <bitops.h> 11f20e2561SAndrew Jones 12f20e2561SAndrew Jones #define CPUMASK_NR_LONGS ((NR_CPUS + BITS_PER_LONG - 1) / BITS_PER_LONG) 13f20e2561SAndrew Jones 14f20e2561SAndrew Jones typedef struct cpumask { 15f20e2561SAndrew Jones unsigned long bits[CPUMASK_NR_LONGS]; 16f20e2561SAndrew Jones } cpumask_t; 17f20e2561SAndrew Jones 18f20e2561SAndrew Jones #define cpumask_bits(maskp) ((maskp)->bits) 19f20e2561SAndrew Jones 20f20e2561SAndrew Jones static inline void cpumask_set_cpu(int cpu, cpumask_t *mask) 21f20e2561SAndrew Jones { 22adae1302SNikos Nikoleris assert(cpu >= 0 && cpu < nr_cpus); 23f20e2561SAndrew Jones set_bit(cpu, cpumask_bits(mask)); 24f20e2561SAndrew Jones } 25f20e2561SAndrew Jones 26f20e2561SAndrew Jones static inline void cpumask_clear_cpu(int cpu, cpumask_t *mask) 27f20e2561SAndrew Jones { 28adae1302SNikos Nikoleris assert(cpu >= 0 && cpu < nr_cpus); 29f20e2561SAndrew Jones clear_bit(cpu, cpumask_bits(mask)); 30f20e2561SAndrew Jones } 31f20e2561SAndrew Jones 32f20e2561SAndrew Jones static inline int cpumask_test_cpu(int cpu, const cpumask_t *mask) 33f20e2561SAndrew Jones { 34adae1302SNikos Nikoleris assert(cpu >= 0 && cpu < nr_cpus); 35f20e2561SAndrew Jones return test_bit(cpu, cpumask_bits(mask)); 36f20e2561SAndrew Jones } 37f20e2561SAndrew Jones 38f20e2561SAndrew Jones static inline int cpumask_test_and_set_cpu(int cpu, cpumask_t *mask) 39f20e2561SAndrew Jones { 40adae1302SNikos Nikoleris assert(cpu >= 0 && cpu < nr_cpus); 41f20e2561SAndrew Jones return test_and_set_bit(cpu, cpumask_bits(mask)); 42f20e2561SAndrew Jones } 43f20e2561SAndrew Jones 44f20e2561SAndrew Jones static inline int cpumask_test_and_clear_cpu(int cpu, cpumask_t *mask) 45f20e2561SAndrew Jones { 46adae1302SNikos Nikoleris assert(cpu >= 0 && cpu < nr_cpus); 47f20e2561SAndrew Jones return test_and_clear_bit(cpu, cpumask_bits(mask)); 48f20e2561SAndrew Jones } 49f20e2561SAndrew Jones 50f20e2561SAndrew Jones static inline void cpumask_setall(cpumask_t *mask) 51f20e2561SAndrew Jones { 52f20e2561SAndrew Jones int i; 53f20e2561SAndrew Jones for (i = 0; i < nr_cpus; i += BITS_PER_LONG) 54f20e2561SAndrew Jones cpumask_bits(mask)[BIT_WORD(i)] = ~0UL; 55f20e2561SAndrew Jones i -= BITS_PER_LONG; 56f20e2561SAndrew Jones if ((nr_cpus - i) < BITS_PER_LONG) 57f20e2561SAndrew Jones cpumask_bits(mask)[BIT_WORD(i)] = BIT_MASK(nr_cpus - i) - 1; 58f20e2561SAndrew Jones } 59f20e2561SAndrew Jones 60f20e2561SAndrew Jones static inline void cpumask_clear(cpumask_t *mask) 61f20e2561SAndrew Jones { 62f20e2561SAndrew Jones int i; 63f20e2561SAndrew Jones for (i = 0; i < nr_cpus; i += BITS_PER_LONG) 64f20e2561SAndrew Jones cpumask_bits(mask)[BIT_WORD(i)] = 0UL; 65f20e2561SAndrew Jones } 66f20e2561SAndrew Jones 67f20e2561SAndrew Jones static inline bool cpumask_empty(const cpumask_t *mask) 68f20e2561SAndrew Jones { 69f20e2561SAndrew Jones int i; 70f20e2561SAndrew Jones for (i = 0; i < nr_cpus; i += BITS_PER_LONG) { 71f20e2561SAndrew Jones if (i < NR_CPUS) { /* silence crazy compiler warning */ 72f20e2561SAndrew Jones if (cpumask_bits(mask)[BIT_WORD(i)] != 0UL) 73f20e2561SAndrew Jones return false; 74f20e2561SAndrew Jones } 75f20e2561SAndrew Jones } 76f20e2561SAndrew Jones return true; 77f20e2561SAndrew Jones } 78f20e2561SAndrew Jones 79f20e2561SAndrew Jones static inline bool cpumask_full(const cpumask_t *mask) 80f20e2561SAndrew Jones { 81f20e2561SAndrew Jones int i; 82f20e2561SAndrew Jones for (i = 0; i < nr_cpus; i += BITS_PER_LONG) { 83f20e2561SAndrew Jones if (cpumask_bits(mask)[BIT_WORD(i)] != ~0UL) { 84f20e2561SAndrew Jones if ((nr_cpus - i) >= BITS_PER_LONG) 85f20e2561SAndrew Jones return false; 86f20e2561SAndrew Jones if (cpumask_bits(mask)[BIT_WORD(i)] 87f20e2561SAndrew Jones != BIT_MASK(nr_cpus - i) - 1) 88f20e2561SAndrew Jones return false; 89f20e2561SAndrew Jones } 90f20e2561SAndrew Jones } 91f20e2561SAndrew Jones return true; 92f20e2561SAndrew Jones } 93f20e2561SAndrew Jones 94f20e2561SAndrew Jones static inline int cpumask_weight(const cpumask_t *mask) 95f20e2561SAndrew Jones { 96f20e2561SAndrew Jones int w = 0, i; 97f20e2561SAndrew Jones 98f20e2561SAndrew Jones for (i = 0; i < nr_cpus; ++i) 99f20e2561SAndrew Jones if (cpumask_test_cpu(i, mask)) 100f20e2561SAndrew Jones ++w; 101f20e2561SAndrew Jones return w; 102f20e2561SAndrew Jones } 103f20e2561SAndrew Jones 104f20e2561SAndrew Jones static inline void cpumask_copy(cpumask_t *dst, const cpumask_t *src) 105f20e2561SAndrew Jones { 106f20e2561SAndrew Jones memcpy(cpumask_bits(dst), cpumask_bits(src), 107f20e2561SAndrew Jones CPUMASK_NR_LONGS * sizeof(long)); 108f20e2561SAndrew Jones } 109f20e2561SAndrew Jones 110f20e2561SAndrew Jones static inline int cpumask_next(int cpu, const cpumask_t *mask) 111f20e2561SAndrew Jones { 112fdab948bSNikos Nikoleris while (++cpu < nr_cpus && !cpumask_test_cpu(cpu, mask)) 113f20e2561SAndrew Jones ; 114f20e2561SAndrew Jones return cpu; 115f20e2561SAndrew Jones } 116f20e2561SAndrew Jones 117f20e2561SAndrew Jones #define for_each_cpu(cpu, mask) \ 118f20e2561SAndrew Jones for ((cpu) = cpumask_next(-1, mask); \ 119f20e2561SAndrew Jones (cpu) < nr_cpus; \ 120f20e2561SAndrew Jones (cpu) = cpumask_next(cpu, mask)) 121f20e2561SAndrew Jones 122*dfc1fec2SAndrew Jones #endif /* _CPUMASK_H_ */ 123