aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/mm/tlb_nohash.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-07-23 19:15:10 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-08-19 20:12:37 -0400
commitfcce810986b3f32a8322faf240f8cc5560a4c463 (patch)
tree4ee99143e18a008c52a274d74c1cc11055983bc6 /arch/powerpc/mm/tlb_nohash.c
parent6c1719942e19936044c4673b18afa26e45a02320 (diff)
powerpc/mm: Add HW threads support to no_hash TLB management
The current "no hash" MMU context management code is written with the assumption that one CPU == one TLB. This is not the case on implementations that support HW multithreading, where several linux CPUs can share the same TLB. This adds some basic support for this to our context management and our TLB flushing code. It also cleans up the optional debugging output a bit Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/mm/tlb_nohash.c')
-rw-r--r--arch/powerpc/mm/tlb_nohash.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c
index ad2eb4d34dd..d908e75cc3b 100644
--- a/arch/powerpc/mm/tlb_nohash.c
+++ b/arch/powerpc/mm/tlb_nohash.c
@@ -87,6 +87,12 @@ EXPORT_SYMBOL(local_flush_tlb_page);
87 87
88static DEFINE_SPINLOCK(tlbivax_lock); 88static DEFINE_SPINLOCK(tlbivax_lock);
89 89
90static int mm_is_core_local(struct mm_struct *mm)
91{
92 return cpumask_subset(mm_cpumask(mm),
93 topology_thread_cpumask(smp_processor_id()));
94}
95
90struct tlb_flush_param { 96struct tlb_flush_param {
91 unsigned long addr; 97 unsigned long addr;
92 unsigned int pid; 98 unsigned int pid;
@@ -131,7 +137,7 @@ void flush_tlb_mm(struct mm_struct *mm)
131 pid = mm->context.id; 137 pid = mm->context.id;
132 if (unlikely(pid == MMU_NO_CONTEXT)) 138 if (unlikely(pid == MMU_NO_CONTEXT))
133 goto no_context; 139 goto no_context;
134 if (!cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) { 140 if (!mm_is_core_local(mm)) {
135 struct tlb_flush_param p = { .pid = pid }; 141 struct tlb_flush_param p = { .pid = pid };
136 /* Ignores smp_processor_id() even if set. */ 142 /* Ignores smp_processor_id() even if set. */
137 smp_call_function_many(mm_cpumask(mm), 143 smp_call_function_many(mm_cpumask(mm),
@@ -153,7 +159,7 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
153 if (unlikely(pid == MMU_NO_CONTEXT)) 159 if (unlikely(pid == MMU_NO_CONTEXT))
154 goto bail; 160 goto bail;
155 cpu_mask = mm_cpumask(vma->vm_mm); 161 cpu_mask = mm_cpumask(vma->vm_mm);
156 if (!cpumask_equal(cpu_mask, cpumask_of(smp_processor_id()))) { 162 if (!mm_is_core_local(mm)) {
157 /* If broadcast tlbivax is supported, use it */ 163 /* If broadcast tlbivax is supported, use it */
158 if (mmu_has_feature(MMU_FTR_USE_TLBIVAX_BCAST)) { 164 if (mmu_has_feature(MMU_FTR_USE_TLBIVAX_BCAST)) {
159 int lock = mmu_has_feature(MMU_FTR_LOCK_BCAST_INVAL); 165 int lock = mmu_has_feature(MMU_FTR_LOCK_BCAST_INVAL);