powerpc: Cleanup APIs for cpu/thread/core mappings
authorVaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
Wed, 6 Oct 2010 08:36:59 +0000 (08:36 +0000)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Mon, 29 Nov 2010 04:48:19 +0000 (15:48 +1100)
These APIs take logical cpu number as input
Change cpu_first_thread_in_core() to cpu_first_thread_sibling()
Change cpu_last_thread_in_core() to cpu_last_thread_sibling()

These APIs convert core number (index) to logical cpu/thread numbers
Add cpu_first_thread_of_core(int core)
Changed cpu_thread_to_core() to cpu_core_index_of_thread(int cpu)

The goal is to make 'threads_per_core' accessible to the
pseries_energy module.  Instead of making an API to read
threads_per_core, this is a higher level wrapper function to
convert from logical cpu number to core number.

The current APIs cpu_first_thread_in_core() and
cpu_last_thread_in_core() returns logical CPU number while
cpu_thread_to_core() returns core number or index which is
not a logical CPU number.  The new APIs are now clearly named to
distinguish 'core number' versus first and last 'logical cpu
number' in that core.

The new APIs cpu_{first,last}_thread_sibling() work on
logical cpu numbers.  While cpu_first_thread_of_core() and
cpu_core_index_of_thread() work on core index.

Example usage:  (4 threads per core system)

cpu_first_thread_sibling(5) = 4
cpu_last_thread_sibling(5) = 7
cpu_core_index_of_thread(5) = 1
cpu_first_thread_of_core(1) = 4

cpu_core_index_of_thread() is used in cpu_to_drc_index() in the
module and cpu_first_thread_of_core() is used in
drc_index_to_cpu() in the module.

Make API changes to few callers.  Export symbols for use in modules.

Signed-off-by: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/include/asm/cputhreads.h
arch/powerpc/kernel/smp.c
arch/powerpc/mm/mmu_context_nohash.c

index a8e18447c62b967d381a09fb5a7f0857753dbd19..f71bb4c118b4566eb8a1149f8f7278d3a03b27ab 100644 (file)
@@ -61,22 +61,25 @@ 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;
-}
+#ifdef CONFIG_SMP
+int cpu_core_index_of_thread(int cpu);
+int cpu_first_thread_of_core(int core);
+#else
+static inline int cpu_core_index_of_thread(int cpu) { return cpu; }
+static inline int cpu_first_thread_of_core(int core) { return core; }
+#endif
 
 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)
+static inline int cpu_first_thread_sibling(int cpu)
 {
        return cpu & ~(threads_per_core - 1);
 }
 
-static inline int cpu_last_thread_in_core(int cpu)
+static inline int cpu_last_thread_sibling(int cpu)
 {
        return cpu | (threads_per_core - 1);
 }
index 68034bbf2e4f0affdeaa991a56b75482b6c3d615..981360509172472a044eac1b9ec50019def24b9c 100644 (file)
@@ -466,7 +466,20 @@ out:
        return id;
 }
 
-/* Must be called when no change can occur to cpu_present_mask,
+/* Helper routines for cpu to core mapping */
+int cpu_core_index_of_thread(int cpu)
+{
+       return cpu >> threads_shift;
+}
+EXPORT_SYMBOL_GPL(cpu_core_index_of_thread);
+
+int cpu_first_thread_of_core(int core)
+{
+       return core << threads_shift;
+}
+EXPORT_SYMBOL_GPL(cpu_first_thread_of_core);
+
+/* Must be called when no change can occur to cpu_present_map,
  * i.e. during cpu online or offline.
  */
 static struct device_node *cpu_to_l2cache(int cpu)
@@ -514,7 +527,7 @@ int __devinit start_secondary(void *unused)
        notify_cpu_starting(cpu);
        set_cpu_online(cpu, true);
        /* Update sibling maps */
-       base = cpu_first_thread_in_core(cpu);
+       base = cpu_first_thread_sibling(cpu);
        for (i = 0; i < threads_per_core; i++) {
                if (cpu_is_offline(base + i))
                        continue;
@@ -600,7 +613,7 @@ int __cpu_disable(void)
                return err;
 
        /* Update sibling maps */
-       base = cpu_first_thread_in_core(cpu);
+       base = cpu_first_thread_sibling(cpu);
        for (i = 0; i < threads_per_core; i++) {
                cpumask_clear_cpu(cpu, cpu_sibling_mask(base + i));
                cpumask_clear_cpu(base + i, cpu_sibling_mask(cpu));
index 5ce99848d91e49aa3fb03d90c0f8c116a4d9d42a..c0aab52da3a56b73f4758ab5c874c9bb1374c68a 100644 (file)
@@ -111,8 +111,8 @@ static unsigned int steal_context_smp(unsigned int id)
                 * a core map instead but this will do for now.
                 */
                for_each_cpu(cpu, mm_cpumask(mm)) {
-                       for (i = cpu_first_thread_in_core(cpu);
-                            i <= cpu_last_thread_in_core(cpu); i++)
+                       for (i = cpu_first_thread_sibling(cpu);
+                            i <= cpu_last_thread_sibling(cpu); i++)
                                __set_bit(id, stale_map[i]);
                        cpu = i - 1;
                }
@@ -264,14 +264,14 @@ void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next)
         */
        if (test_bit(id, stale_map[cpu])) {
                pr_hardcont(" | stale flush %d [%d..%d]",
-                           id, cpu_first_thread_in_core(cpu),
-                           cpu_last_thread_in_core(cpu));
+                           id, cpu_first_thread_sibling(cpu),
+                           cpu_last_thread_sibling(cpu));
 
                local_flush_tlb_mm(next);
 
                /* XXX This clear should ultimately be part of local_flush_tlb_mm */
-               for (i = cpu_first_thread_in_core(cpu);
-                    i <= cpu_last_thread_in_core(cpu); i++) {
+               for (i = cpu_first_thread_sibling(cpu);
+                    i <= cpu_last_thread_sibling(cpu); i++) {
                        __clear_bit(id, stale_map[i]);
                }
        }