linux-hardened/include/asm-powerpc/cputhreads.h
Benjamin Herrenschmidt 6a2d322e4b [POWERPC] Fix thinko in cpu_thread_mask_to_cores()
The function cpu_thread_mask_to_cores() which returns a cpumask
of one and only one thread enabled for a given core has a bug
as it's shifting things in the wrong direction.

Note: The implementation is still sub-optimal in the sense that
for a given core, the thread set in the result may not be any of
the threads set in the input, which can lead to more IPIs then
strictly necessary, but it isn't incorrect per-se.  I'll improve
that later.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
2008-02-26 22:17:03 +11:00

71 lines
1.5 KiB
C

#ifndef _ASM_POWERPC_CPUTHREADS_H
#define _ASM_POWERPC_CPUTHREADS_H
#include <linux/cpumask.h>
/*
* Mapping of threads to cores
*/
#ifdef CONFIG_SMP
extern int threads_per_core;
extern int threads_shift;
extern cpumask_t threads_core_mask;
#else
#define threads_per_core 1
#define threads_shift 0
#define threads_core_mask (CPU_MASK_CPU0)
#endif
/* cpu_thread_mask_to_cores - Return a cpumask of one per cores
* hit by the argument
*
* @threads: a cpumask of threads
*
* This function returns a cpumask which will have one "cpu" (or thread)
* bit set for each core that has at least one thread set in the argument.
*
* This can typically be used for things like IPI for tlb invalidations
* since those need to be done only once per core/TLB
*/
static inline cpumask_t cpu_thread_mask_to_cores(cpumask_t threads)
{
cpumask_t tmp, res;
int i;
res = CPU_MASK_NONE;
for (i = 0; i < NR_CPUS; i += threads_per_core) {
cpus_shift_left(tmp, threads_core_mask, i);
if (cpus_intersects(threads, tmp))
cpu_set(i, res);
}
return res;
}
static inline int cpu_nr_cores(void)
{
return NR_CPUS >> threads_shift;
}
static inline cpumask_t cpu_online_cores_map(void)
{
return cpu_thread_mask_to_cores(cpu_online_map);
}
static inline int cpu_thread_to_core(int cpu)
{
return cpu >> threads_shift;
}
static inline int cpu_thread_in_core(int cpu)
{
return cpu & (threads_per_core - 1);
}
static inline int cpu_first_thread_in_core(int cpu)
{
return cpu & ~(threads_per_core - 1);
}
#endif /* _ASM_POWERPC_CPUTHREADS_H */