1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef __LINUX_CPUMASK_TYPES_H 3 #define __LINUX_CPUMASK_TYPES_H 4 5 #include <linux/bitops.h> 6 #include <linux/threads.h> 7 8 /* Don't assign or return these: may not be this big! */ 9 typedef struct cpumask { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t; 10 11 /** 12 * cpumask_bits - get the bits in a cpumask 13 * @maskp: the struct cpumask * 14 * 15 * You should only assume nr_cpu_ids bits of this mask are valid. This is 16 * a macro so it's const-correct. 17 */ 18 #define cpumask_bits(maskp) ((maskp)->bits) 19 20 /* 21 * cpumask_var_t: struct cpumask for stack usage. 22 * 23 * Oh, the wicked games we play! In order to make kernel coding a 24 * little more difficult, we typedef cpumask_var_t to an array or a 25 * pointer: doing &mask on an array is a noop, so it still works. 26 * 27 * i.e. 28 * cpumask_var_t tmpmask; 29 * if (!alloc_cpumask_var(&tmpmask, GFP_KERNEL)) 30 * return -ENOMEM; 31 * 32 * ... use 'tmpmask' like a normal struct cpumask * ... 33 * 34 * free_cpumask_var(tmpmask); 35 * 36 * 37 * However, one notable exception is there. alloc_cpumask_var() allocates 38 * only nr_cpumask_bits bits (in the other hand, real cpumask_t always has 39 * NR_CPUS bits). Therefore you don't have to dereference cpumask_var_t. 40 * 41 * cpumask_var_t tmpmask; 42 * if (!alloc_cpumask_var(&tmpmask, GFP_KERNEL)) 43 * return -ENOMEM; 44 * 45 * var = *tmpmask; 46 * 47 * This code makes NR_CPUS length memcopy and brings to a memory corruption. 48 * cpumask_copy() provide safe copy functionality. 49 * 50 * Note that there is another evil here: If you define a cpumask_var_t 51 * as a percpu variable then the way to obtain the address of the cpumask 52 * structure differently influences what this_cpu_* operation needs to be 53 * used. Please use this_cpu_cpumask_var_t in those cases. The direct use 54 * of this_cpu_ptr() or this_cpu_read() will lead to failures when the 55 * other type of cpumask_var_t implementation is configured. 56 * 57 * Please also note that __cpumask_var_read_mostly can be used to declare 58 * a cpumask_var_t variable itself (not its content) as read mostly. 59 */ 60 #ifdef CONFIG_CPUMASK_OFFSTACK 61 typedef struct cpumask *cpumask_var_t; 62 #else 63 typedef struct cpumask cpumask_var_t[1]; 64 #endif /* CONFIG_CPUMASK_OFFSTACK */ 65 66 #endif /* __LINUX_CPUMASK_TYPES_H */ 67