Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

bitmap: generalize node_random()

Generalize node_random() and make it available to general bitmaps and
cpumasks users.

Notice, find_first_bit() is generally faster than find_nth_bit(), and we
employ it when there's a single set bit in the bitmap.

See commit 3e061d924fe9c7b4 ("lib/nodemask: optimize node_random for
nodemask with single NUMA node").

CC: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: "Yury Norov [NVIDIA]" <yury.norov@gmail.com>

+28 -14
+2
include/linux/find.h
··· 44 44 long size, unsigned long offset); 45 45 #endif 46 46 47 + unsigned long find_random_bit(const unsigned long *addr, unsigned long size); 48 + 47 49 #ifndef find_next_bit 48 50 /** 49 51 * find_next_bit - find the next set bit in a memory region
+2 -14
include/linux/nodemask.h
··· 492 492 static __always_inline int node_random(const nodemask_t *maskp) 493 493 { 494 494 #if defined(CONFIG_NUMA) && (MAX_NUMNODES > 1) 495 - int w, bit; 495 + int node = find_random_bit(maskp->bits, MAX_NUMNODES); 496 496 497 - w = nodes_weight(*maskp); 498 - switch (w) { 499 - case 0: 500 - bit = NUMA_NO_NODE; 501 - break; 502 - case 1: 503 - bit = first_node(*maskp); 504 - break; 505 - default: 506 - bit = find_nth_bit(maskp->bits, MAX_NUMNODES, get_random_u32_below(w)); 507 - break; 508 - } 509 - return bit; 497 + return node < MAX_NUMNODES ? node : NUMA_NO_NODE; 510 498 #else 511 499 return 0; 512 500 #endif
+24
lib/find_bit.c
··· 18 18 #include <linux/math.h> 19 19 #include <linux/minmax.h> 20 20 #include <linux/swab.h> 21 + #include <linux/random.h> 21 22 22 23 /* 23 24 * Common helper for find_bit() function family ··· 292 291 #endif 293 292 294 293 #endif /* __BIG_ENDIAN */ 294 + 295 + /** 296 + * find_random_bit - find a set bit at random position 297 + * @addr: The address to base the search on 298 + * @size: The bitmap size in bits 299 + * 300 + * Returns: a position of a random set bit; >= @size otherwise 301 + */ 302 + unsigned long find_random_bit(const unsigned long *addr, unsigned long size) 303 + { 304 + int w = bitmap_weight(addr, size); 305 + 306 + switch (w) { 307 + case 0: 308 + return size; 309 + case 1: 310 + /* Performance trick for single-bit bitmaps */ 311 + return find_first_bit(addr, size); 312 + default: 313 + return find_nth_bit(addr, size, get_random_u32_below(w)); 314 + } 315 + } 316 + EXPORT_SYMBOL(find_random_bit);