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 3e061d924f
("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>
This commit is contained in:
parent
733923397f
commit
c56f97c5c7
|
@ -44,6 +44,8 @@ unsigned long _find_next_bit_le(const unsigned long *addr, unsigned
|
|||
long size, unsigned long offset);
|
||||
#endif
|
||||
|
||||
unsigned long find_random_bit(const unsigned long *addr, unsigned long size);
|
||||
|
||||
#ifndef find_next_bit
|
||||
/**
|
||||
* find_next_bit - find the next set bit in a memory region
|
||||
|
|
|
@ -492,21 +492,9 @@ static __always_inline int num_node_state(enum node_states state)
|
|||
static __always_inline int node_random(const nodemask_t *maskp)
|
||||
{
|
||||
#if defined(CONFIG_NUMA) && (MAX_NUMNODES > 1)
|
||||
int w, bit;
|
||||
int node = find_random_bit(maskp->bits, MAX_NUMNODES);
|
||||
|
||||
w = nodes_weight(*maskp);
|
||||
switch (w) {
|
||||
case 0:
|
||||
bit = NUMA_NO_NODE;
|
||||
break;
|
||||
case 1:
|
||||
bit = first_node(*maskp);
|
||||
break;
|
||||
default:
|
||||
bit = find_nth_bit(maskp->bits, MAX_NUMNODES, get_random_u32_below(w));
|
||||
break;
|
||||
}
|
||||
return bit;
|
||||
return node < MAX_NUMNODES ? node : NUMA_NO_NODE;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <linux/math.h>
|
||||
#include <linux/minmax.h>
|
||||
#include <linux/swab.h>
|
||||
#include <linux/random.h>
|
||||
|
||||
/*
|
||||
* Common helper for find_bit() function family
|
||||
|
@ -291,3 +292,26 @@ EXPORT_SYMBOL(_find_next_bit_le);
|
|||
#endif
|
||||
|
||||
#endif /* __BIG_ENDIAN */
|
||||
|
||||
/**
|
||||
* find_random_bit - find a set bit at random position
|
||||
* @addr: The address to base the search on
|
||||
* @size: The bitmap size in bits
|
||||
*
|
||||
* Returns: a position of a random set bit; >= @size otherwise
|
||||
*/
|
||||
unsigned long find_random_bit(const unsigned long *addr, unsigned long size)
|
||||
{
|
||||
int w = bitmap_weight(addr, size);
|
||||
|
||||
switch (w) {
|
||||
case 0:
|
||||
return size;
|
||||
case 1:
|
||||
/* Performance trick for single-bit bitmaps */
|
||||
return find_first_bit(addr, size);
|
||||
default:
|
||||
return find_nth_bit(addr, size, get_random_u32_below(w));
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(find_random_bit);
|
||||
|
|
Loading…
Reference in New Issue