diff options
author | Jan Beulich <jbeulich@suse.com> | 2013-08-23 15:01:53 +0200 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2013-08-23 15:01:53 +0200 |
commit | 829b8498cc781f5ed8f7b9e16378f448b4d45213 (patch) | |
tree | fa6057dc0bf1586818a82815a0fff3243a969f21 /xen/include/xen | |
parent | 3829655bd3ad2b1150bd94955fc6988dec6b98f2 (diff) | |
download | xen-829b8498cc781f5ed8f7b9e16378f448b4d45213.tar.gz xen-829b8498cc781f5ed8f7b9e16378f448b4d45213.tar.bz2 xen-829b8498cc781f5ed8f7b9e16378f448b4d45213.zip |
un-alias cpumask_any() from cpumask_first()
In order to achieve more symmetric distribution of certain things,
cpumask_any() shouldn't always pick the first CPU (which frequently
will end up being CPU0). To facilitate that, introduce a library-like
function to obtain random numbers.
The per-architecture function is supposed to return zero if no valid
random number can be obtained (implying that if occasionally zero got
produced as random number, it wouldn't be considered such).
As fallback this uses the trivial algorithm from the C standard,
extended to produce "unsigned int" results.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
Reviewed-by: George Dunlap <george.dunlap@eu.citrix.com>
Diffstat (limited to 'xen/include/xen')
-rw-r--r-- | xen/include/xen/cpumask.h | 19 | ||||
-rw-r--r-- | xen/include/xen/random.h | 6 |
2 files changed, 24 insertions, 1 deletions
diff --git a/xen/include/xen/cpumask.h b/xen/include/xen/cpumask.h index f931cf2618..850b4a22d7 100644 --- a/xen/include/xen/cpumask.h +++ b/xen/include/xen/cpumask.h @@ -77,6 +77,7 @@ #include <xen/bitmap.h> #include <xen/kernel.h> +#include <xen/random.h> typedef struct cpumask{ DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t; @@ -245,7 +246,23 @@ static inline int cpumask_cycle(int n, const cpumask_t *srcp) return nxt; } -#define cpumask_any(srcp) cpumask_first(srcp) +static inline unsigned int cpumask_any(const cpumask_t *srcp) +{ + unsigned int cpu = cpumask_first(srcp); + unsigned int w = cpumask_weight(srcp); + + if ( w > 1 && cpu < nr_cpu_ids ) + for ( w = get_random() % w; w--; ) + { + unsigned int next = cpumask_next(cpu, srcp); + + if ( next >= nr_cpu_ids ) + break; + cpu = next; + } + + return cpu; +} /* * Special-case data structure for "single bit set only" constant CPU masks. diff --git a/xen/include/xen/random.h b/xen/include/xen/random.h new file mode 100644 index 0000000000..7c43d87f59 --- /dev/null +++ b/xen/include/xen/random.h @@ -0,0 +1,6 @@ +#ifndef __XEN_RANDOM_H__ +#define __XEN_RANDOM_H__ + +unsigned int get_random(void); + +#endif /* __XEN_RANDOM_H__ */ |