Home | History | Annotate | Download | only in linux
      1 #ifndef __LINUX_NODEMASK_H
      2 #define __LINUX_NODEMASK_H
      3 
      4 /*
      5  * Nodemasks provide a bitmap suitable for representing the
      6  * set of Node's in a system, one bit position per Node number.
      7  *
      8  * See detailed comments in the file linux/bitmap.h describing the
      9  * data type on which these nodemasks are based.
     10  *
     11  * For details of nodemask_scnprintf() and nodemask_parse(),
     12  * see bitmap_scnprintf() and bitmap_parse() in lib/bitmap.c.
     13  * For details of nodelist_scnprintf() and nodelist_parse(), see
     14  * bitmap_scnlistprintf() and bitmap_parselist(), also in bitmap.c.
     15  * For details of node_remap(), see bitmap_bitremap in lib/bitmap.c.
     16  * For details of nodes_remap(), see bitmap_remap in lib/bitmap.c.
     17  *
     18  * The available nodemask operations are:
     19  *
     20  * void node_set(node, mask)		turn on bit 'node' in mask
     21  * void node_clear(node, mask)		turn off bit 'node' in mask
     22  * void nodes_setall(mask)		set all bits
     23  * void nodes_clear(mask)		clear all bits
     24  * int node_isset(node, mask)		true iff bit 'node' set in mask
     25  * int node_test_and_set(node, mask)	test and set bit 'node' in mask
     26  *
     27  * void nodes_and(dst, src1, src2)	dst = src1 & src2  [intersection]
     28  * void nodes_or(dst, src1, src2)	dst = src1 | src2  [union]
     29  * void nodes_xor(dst, src1, src2)	dst = src1 ^ src2
     30  * void nodes_andnot(dst, src1, src2)	dst = src1 & ~src2
     31  * void nodes_complement(dst, src)	dst = ~src
     32  *
     33  * int nodes_equal(mask1, mask2)	Does mask1 == mask2?
     34  * int nodes_intersects(mask1, mask2)	Do mask1 and mask2 intersect?
     35  * int nodes_subset(mask1, mask2)	Is mask1 a subset of mask2?
     36  * int nodes_empty(mask)		Is mask empty (no bits sets)?
     37  * int nodes_full(mask)			Is mask full (all bits sets)?
     38  * int nodes_weight(mask)		Hamming weight - number of set bits
     39  *
     40  * void nodes_shift_right(dst, src, n)	Shift right
     41  * void nodes_shift_left(dst, src, n)	Shift left
     42  *
     43  * int first_node(mask)			Number lowest set bit, or MAX_NUMNODES
     44  * int next_node(node, mask)		Next node past 'node', or MAX_NUMNODES
     45  * int first_unset_node(mask)		First node not set in mask, or
     46  *					MAX_NUMNODES.
     47  *
     48  * nodemask_t nodemask_of_node(node)	Return nodemask with bit 'node' set
     49  * NODE_MASK_ALL			Initializer - all bits set
     50  * NODE_MASK_NONE			Initializer - no bits set
     51  * unsigned long *nodes_addr(mask)	Array of unsigned long's in mask
     52  *
     53  * int nodemask_scnprintf(buf, len, mask) Format nodemask for printing
     54  * int nodemask_parse(ubuf, ulen, mask)	Parse ascii string as nodemask
     55  * int nodelist_scnprintf(buf, len, mask) Format nodemask as list for printing
     56  * int nodelist_parse(buf, map)		Parse ascii string as nodelist
     57  * int node_remap(oldbit, old, new)	newbit = map(old, new)(oldbit)
     58  * int nodes_remap(dst, src, old, new)	*dst = map(old, new)(dst)
     59  *
     60  * for_each_node_mask(node, mask)	for-loop node over mask
     61  *
     62  * int num_online_nodes()		Number of online Nodes
     63  * int num_possible_nodes()		Number of all possible Nodes
     64  *
     65  * int node_online(node)		Is some node online?
     66  * int node_possible(node)		Is some node possible?
     67  *
     68  * int any_online_node(mask)		First online node in mask
     69  *
     70  * node_set_online(node)		set bit 'node' in node_online_map
     71  * node_set_offline(node)		clear bit 'node' in node_online_map
     72  *
     73  * for_each_node(node)			for-loop node over node_possible_map
     74  * for_each_online_node(node)		for-loop node over node_online_map
     75  *
     76  * Subtlety:
     77  * 1) The 'type-checked' form of node_isset() causes gcc (3.3.2, anyway)
     78  *    to generate slightly worse code.  So use a simple one-line #define
     79  *    for node_isset(), instead of wrapping an inline inside a macro, the
     80  *    way we do the other calls.
     81  */
     82 
     83 #include <linux/kernel.h>
     84 #include <linux/threads.h>
     85 #include <linux/bitmap.h>
     86 #include <linux/numa.h>
     87 
     88 typedef struct { DECLARE_BITMAP(bits, MAX_NUMNODES); } nodemask_t;
     89 extern nodemask_t _unused_nodemask_arg_;
     90 
     91 #define node_set(node, dst) __node_set((node), &(dst))
     92 static inline void __node_set(int node, volatile nodemask_t *dstp)
     93 {
     94 	set_bit(node, dstp->bits);
     95 }
     96 
     97 #define node_clear(node, dst) __node_clear((node), &(dst))
     98 static inline void __node_clear(int node, volatile nodemask_t *dstp)
     99 {
    100 	clear_bit(node, dstp->bits);
    101 }
    102 
    103 #define nodes_setall(dst) __nodes_setall(&(dst), MAX_NUMNODES)
    104 static inline void __nodes_setall(nodemask_t *dstp, int nbits)
    105 {
    106 	bitmap_fill(dstp->bits, nbits);
    107 }
    108 
    109 #define nodes_clear(dst) __nodes_clear(&(dst), MAX_NUMNODES)
    110 static inline void __nodes_clear(nodemask_t *dstp, int nbits)
    111 {
    112 	bitmap_zero(dstp->bits, nbits);
    113 }
    114 
    115 /* No static inline type checking - see Subtlety (1) above. */
    116 #define node_isset(node, nodemask) test_bit((node), (nodemask).bits)
    117 
    118 #define node_test_and_set(node, nodemask) \
    119 			__node_test_and_set((node), &(nodemask))
    120 static inline int __node_test_and_set(int node, nodemask_t *addr)
    121 {
    122 	return test_and_set_bit(node, addr->bits);
    123 }
    124 
    125 #define nodes_and(dst, src1, src2) \
    126 			__nodes_and(&(dst), &(src1), &(src2), MAX_NUMNODES)
    127 static inline void __nodes_and(nodemask_t *dstp, const nodemask_t *src1p,
    128 					const nodemask_t *src2p, int nbits)
    129 {
    130 	bitmap_and(dstp->bits, src1p->bits, src2p->bits, nbits);
    131 }
    132 
    133 #define nodes_or(dst, src1, src2) \
    134 			__nodes_or(&(dst), &(src1), &(src2), MAX_NUMNODES)
    135 static inline void __nodes_or(nodemask_t *dstp, const nodemask_t *src1p,
    136 					const nodemask_t *src2p, int nbits)
    137 {
    138 	bitmap_or(dstp->bits, src1p->bits, src2p->bits, nbits);
    139 }
    140 
    141 #define nodes_xor(dst, src1, src2) \
    142 			__nodes_xor(&(dst), &(src1), &(src2), MAX_NUMNODES)
    143 static inline void __nodes_xor(nodemask_t *dstp, const nodemask_t *src1p,
    144 					const nodemask_t *src2p, int nbits)
    145 {
    146 	bitmap_xor(dstp->bits, src1p->bits, src2p->bits, nbits);
    147 }
    148 
    149 #define nodes_andnot(dst, src1, src2) \
    150 			__nodes_andnot(&(dst), &(src1), &(src2), MAX_NUMNODES)
    151 static inline void __nodes_andnot(nodemask_t *dstp, const nodemask_t *src1p,
    152 					const nodemask_t *src2p, int nbits)
    153 {
    154 	bitmap_andnot(dstp->bits, src1p->bits, src2p->bits, nbits);
    155 }
    156 
    157 #define nodes_complement(dst, src) \
    158 			__nodes_complement(&(dst), &(src), MAX_NUMNODES)
    159 static inline void __nodes_complement(nodemask_t *dstp,
    160 					const nodemask_t *srcp, int nbits)
    161 {
    162 	bitmap_complement(dstp->bits, srcp->bits, nbits);
    163 }
    164 
    165 #define nodes_equal(src1, src2) \
    166 			__nodes_equal(&(src1), &(src2), MAX_NUMNODES)
    167 static inline int __nodes_equal(const nodemask_t *src1p,
    168 					const nodemask_t *src2p, int nbits)
    169 {
    170 	return bitmap_equal(src1p->bits, src2p->bits, nbits);
    171 }
    172 
    173 #define nodes_intersects(src1, src2) \
    174 			__nodes_intersects(&(src1), &(src2), MAX_NUMNODES)
    175 static inline int __nodes_intersects(const nodemask_t *src1p,
    176 					const nodemask_t *src2p, int nbits)
    177 {
    178 	return bitmap_intersects(src1p->bits, src2p->bits, nbits);
    179 }
    180 
    181 #define nodes_subset(src1, src2) \
    182 			__nodes_subset(&(src1), &(src2), MAX_NUMNODES)
    183 static inline int __nodes_subset(const nodemask_t *src1p,
    184 					const nodemask_t *src2p, int nbits)
    185 {
    186 	return bitmap_subset(src1p->bits, src2p->bits, nbits);
    187 }
    188 
    189 #define nodes_empty(src) __nodes_empty(&(src), MAX_NUMNODES)
    190 static inline int __nodes_empty(const nodemask_t *srcp, int nbits)
    191 {
    192 	return bitmap_empty(srcp->bits, nbits);
    193 }
    194 
    195 #define nodes_full(nodemask) __nodes_full(&(nodemask), MAX_NUMNODES)
    196 static inline int __nodes_full(const nodemask_t *srcp, int nbits)
    197 {
    198 	return bitmap_full(srcp->bits, nbits);
    199 }
    200 
    201 #define nodes_weight(nodemask) __nodes_weight(&(nodemask), MAX_NUMNODES)
    202 static inline int __nodes_weight(const nodemask_t *srcp, int nbits)
    203 {
    204 	return bitmap_weight(srcp->bits, nbits);
    205 }
    206 
    207 #define nodes_shift_right(dst, src, n) \
    208 			__nodes_shift_right(&(dst), &(src), (n), MAX_NUMNODES)
    209 static inline void __nodes_shift_right(nodemask_t *dstp,
    210 					const nodemask_t *srcp, int n, int nbits)
    211 {
    212 	bitmap_shift_right(dstp->bits, srcp->bits, n, nbits);
    213 }
    214 
    215 #define nodes_shift_left(dst, src, n) \
    216 			__nodes_shift_left(&(dst), &(src), (n), MAX_NUMNODES)
    217 static inline void __nodes_shift_left(nodemask_t *dstp,
    218 					const nodemask_t *srcp, int n, int nbits)
    219 {
    220 	bitmap_shift_left(dstp->bits, srcp->bits, n, nbits);
    221 }
    222 
    223 /* FIXME: better would be to fix all architectures to never return
    224           > MAX_NUMNODES, then the silly min_ts could be dropped. */
    225 
    226 #define first_node(src) __first_node(&(src))
    227 static inline int __first_node(const nodemask_t *srcp)
    228 {
    229 	return min_t(int, MAX_NUMNODES, find_first_bit(srcp->bits, MAX_NUMNODES));
    230 }
    231 
    232 #define next_node(n, src) __next_node((n), &(src))
    233 static inline int __next_node(int n, const nodemask_t *srcp)
    234 {
    235 	return min_t(int,MAX_NUMNODES,find_next_bit(srcp->bits, MAX_NUMNODES, n+1));
    236 }
    237 
    238 #define nodemask_of_node(node)						\
    239 ({									\
    240 	typeof(_unused_nodemask_arg_) m;				\
    241 	if (sizeof(m) == sizeof(unsigned long)) {			\
    242 		m.bits[0] = 1UL<<(node);				\
    243 	} else {							\
    244 		nodes_clear(m);						\
    245 		node_set((node), m);					\
    246 	}								\
    247 	m;								\
    248 })
    249 
    250 #define first_unset_node(mask) __first_unset_node(&(mask))
    251 static inline int __first_unset_node(const nodemask_t *maskp)
    252 {
    253 	return min_t(int,MAX_NUMNODES,
    254 			find_first_zero_bit(maskp->bits, MAX_NUMNODES));
    255 }
    256 
    257 #define NODE_MASK_LAST_WORD BITMAP_LAST_WORD_MASK(MAX_NUMNODES)
    258 
    259 #if MAX_NUMNODES <= BITS_PER_LONG
    260 
    261 #define NODE_MASK_ALL							\
    262 ((nodemask_t) { {							\
    263 	[BITS_TO_LONGS(MAX_NUMNODES)-1] = NODE_MASK_LAST_WORD		\
    264 } })
    265 
    266 #else
    267 
    268 #define NODE_MASK_ALL							\
    269 ((nodemask_t) { {							\
    270 	[0 ... BITS_TO_LONGS(MAX_NUMNODES)-2] = ~0UL,			\
    271 	[BITS_TO_LONGS(MAX_NUMNODES)-1] = NODE_MASK_LAST_WORD		\
    272 } })
    273 
    274 #endif
    275 
    276 #define NODE_MASK_NONE							\
    277 ((nodemask_t) { {							\
    278 	[0 ... BITS_TO_LONGS(MAX_NUMNODES)-1] =  0UL			\
    279 } })
    280 
    281 #define nodes_addr(src) ((src).bits)
    282 
    283 #define nodemask_scnprintf(buf, len, src) \
    284 			__nodemask_scnprintf((buf), (len), &(src), MAX_NUMNODES)
    285 static inline int __nodemask_scnprintf(char *buf, int len,
    286 					const nodemask_t *srcp, int nbits)
    287 {
    288 	return bitmap_scnprintf(buf, len, srcp->bits, nbits);
    289 }
    290 
    291 #define nodemask_parse(ubuf, ulen, dst) \
    292 			__nodemask_parse((ubuf), (ulen), &(dst), MAX_NUMNODES)
    293 static inline int __nodemask_parse(const char __user *buf, int len,
    294 					nodemask_t *dstp, int nbits)
    295 {
    296 	return bitmap_parse(buf, len, dstp->bits, nbits);
    297 }
    298 
    299 #define nodelist_scnprintf(buf, len, src) \
    300 			__nodelist_scnprintf((buf), (len), &(src), MAX_NUMNODES)
    301 static inline int __nodelist_scnprintf(char *buf, int len,
    302 					const nodemask_t *srcp, int nbits)
    303 {
    304 	return bitmap_scnlistprintf(buf, len, srcp->bits, nbits);
    305 }
    306 
    307 #define nodelist_parse(buf, dst) __nodelist_parse((buf), &(dst), MAX_NUMNODES)
    308 static inline int __nodelist_parse(const char *buf, nodemask_t *dstp, int nbits)
    309 {
    310 	return bitmap_parselist(buf, dstp->bits, nbits);
    311 }
    312 
    313 #define node_remap(oldbit, old, new) \
    314 		__node_remap((oldbit), &(old), &(new), MAX_NUMNODES)
    315 static inline int __node_remap(int oldbit,
    316 		const nodemask_t *oldp, const nodemask_t *newp, int nbits)
    317 {
    318 	return bitmap_bitremap(oldbit, oldp->bits, newp->bits, nbits);
    319 }
    320 
    321 #define nodes_remap(dst, src, old, new) \
    322 		__nodes_remap(&(dst), &(src), &(old), &(new), MAX_NUMNODES)
    323 static inline void __nodes_remap(nodemask_t *dstp, const nodemask_t *srcp,
    324 		const nodemask_t *oldp, const nodemask_t *newp, int nbits)
    325 {
    326 	bitmap_remap(dstp->bits, srcp->bits, oldp->bits, newp->bits, nbits);
    327 }
    328 
    329 #if MAX_NUMNODES > 1
    330 #define for_each_node_mask(node, mask)			\
    331 	for ((node) = first_node(mask);			\
    332 		(node) < MAX_NUMNODES;			\
    333 		(node) = next_node((node), (mask)))
    334 #else /* MAX_NUMNODES == 1 */
    335 #define for_each_node_mask(node, mask)			\
    336 	if (!nodes_empty(mask))				\
    337 		for ((node) = 0; (node) < 1; (node)++)
    338 #endif /* MAX_NUMNODES */
    339 
    340 /*
    341  * The following particular system nodemasks and operations
    342  * on them manage all possible and online nodes.
    343  */
    344 
    345 extern nodemask_t node_online_map;
    346 extern nodemask_t node_possible_map;
    347 
    348 #if MAX_NUMNODES > 1
    349 #define num_online_nodes()	nodes_weight(node_online_map)
    350 #define num_possible_nodes()	nodes_weight(node_possible_map)
    351 #define node_online(node)	node_isset((node), node_online_map)
    352 #define node_possible(node)	node_isset((node), node_possible_map)
    353 #define first_online_node	first_node(node_online_map)
    354 #define next_online_node(nid)	next_node((nid), node_online_map)
    355 #else
    356 #define num_online_nodes()	1
    357 #define num_possible_nodes()	1
    358 #define node_online(node)	((node) == 0)
    359 #define node_possible(node)	((node) == 0)
    360 #define first_online_node	0
    361 #define next_online_node(nid)	(MAX_NUMNODES)
    362 #endif
    363 
    364 #define any_online_node(mask)			\
    365 ({						\
    366 	int node;				\
    367 	for_each_node_mask(node, (mask))	\
    368 		if (node_online(node))		\
    369 			break;			\
    370 	node;					\
    371 })
    372 
    373 #define node_set_online(node)	   set_bit((node), node_online_map.bits)
    374 #define node_set_offline(node)	   clear_bit((node), node_online_map.bits)
    375 
    376 #define for_each_node(node)	   for_each_node_mask((node), node_possible_map)
    377 #define for_each_online_node(node) for_each_node_mask((node), node_online_map)
    378 
    379 #endif /* __LINUX_NODEMASK_H */
    380