aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/mm/tlb-flush.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2006-12-24 19:51:47 -0500
committerPaul Mundt <lethal@linux-sh.org>2007-02-12 20:54:45 -0500
commitaec5e0e1c179fac4bbca4007a3f0d3107275a73c (patch)
tree3b251e52a89445a5546f398fb16a002435b6c2b6 /arch/sh/mm/tlb-flush.c
parent506b85f4114b912d2e91fab8da9849289e43857f (diff)
sh: Use a per-cpu ASID cache.
Previously this was implemented using a global cache, cache this per-CPU instead and bump up the number of context IDs to match NR_CPUS. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/mm/tlb-flush.c')
-rw-r--r--arch/sh/mm/tlb-flush.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/arch/sh/mm/tlb-flush.c b/arch/sh/mm/tlb-flush.c
index ef3e4d477864..b829c17c1d17 100644
--- a/arch/sh/mm/tlb-flush.c
+++ b/arch/sh/mm/tlb-flush.c
@@ -16,12 +16,14 @@
16 16
17void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) 17void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
18{ 18{
19 if (vma->vm_mm && vma->vm_mm->context.id != NO_CONTEXT) { 19 unsigned int cpu = smp_processor_id();
20
21 if (vma->vm_mm && cpu_context(cpu, vma->vm_mm) != NO_CONTEXT) {
20 unsigned long flags; 22 unsigned long flags;
21 unsigned long asid; 23 unsigned long asid;
22 unsigned long saved_asid = MMU_NO_ASID; 24 unsigned long saved_asid = MMU_NO_ASID;
23 25
24 asid = vma->vm_mm->context.id & MMU_CONTEXT_ASID_MASK; 26 asid = cpu_asid(cpu, vma->vm_mm);
25 page &= PAGE_MASK; 27 page &= PAGE_MASK;
26 28
27 local_irq_save(flags); 29 local_irq_save(flags);
@@ -40,22 +42,23 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
40 unsigned long end) 42 unsigned long end)
41{ 43{
42 struct mm_struct *mm = vma->vm_mm; 44 struct mm_struct *mm = vma->vm_mm;
45 unsigned int cpu = smp_processor_id();
43 46
44 if (mm->context.id != NO_CONTEXT) { 47 if (cpu_context(cpu, mm) != NO_CONTEXT) {
45 unsigned long flags; 48 unsigned long flags;
46 int size; 49 int size;
47 50
48 local_irq_save(flags); 51 local_irq_save(flags);
49 size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; 52 size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
50 if (size > (MMU_NTLB_ENTRIES/4)) { /* Too many TLB to flush */ 53 if (size > (MMU_NTLB_ENTRIES/4)) { /* Too many TLB to flush */
51 mm->context.id = NO_CONTEXT; 54 cpu_context(cpu, mm) = NO_CONTEXT;
52 if (mm == current->mm) 55 if (mm == current->mm)
53 activate_context(mm); 56 activate_context(mm, cpu);
54 } else { 57 } else {
55 unsigned long asid; 58 unsigned long asid;
56 unsigned long saved_asid = MMU_NO_ASID; 59 unsigned long saved_asid = MMU_NO_ASID;
57 60
58 asid = mm->context.id & MMU_CONTEXT_ASID_MASK; 61 asid = cpu_asid(cpu, mm);
59 start &= PAGE_MASK; 62 start &= PAGE_MASK;
60 end += (PAGE_SIZE - 1); 63 end += (PAGE_SIZE - 1);
61 end &= PAGE_MASK; 64 end &= PAGE_MASK;
@@ -76,6 +79,7 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
76 79
77void flush_tlb_kernel_range(unsigned long start, unsigned long end) 80void flush_tlb_kernel_range(unsigned long start, unsigned long end)
78{ 81{
82 unsigned int cpu = smp_processor_id();
79 unsigned long flags; 83 unsigned long flags;
80 int size; 84 int size;
81 85
@@ -87,7 +91,7 @@ void flush_tlb_kernel_range(unsigned long start, unsigned long end)
87 unsigned long asid; 91 unsigned long asid;
88 unsigned long saved_asid = get_asid(); 92 unsigned long saved_asid = get_asid();
89 93
90 asid = init_mm.context.id & MMU_CONTEXT_ASID_MASK; 94 asid = cpu_asid(cpu, &init_mm);
91 start &= PAGE_MASK; 95 start &= PAGE_MASK;
92 end += (PAGE_SIZE - 1); 96 end += (PAGE_SIZE - 1);
93 end &= PAGE_MASK; 97 end &= PAGE_MASK;
@@ -103,15 +107,17 @@ void flush_tlb_kernel_range(unsigned long start, unsigned long end)
103 107
104void flush_tlb_mm(struct mm_struct *mm) 108void flush_tlb_mm(struct mm_struct *mm)
105{ 109{
110 unsigned int cpu = smp_processor_id();
111
106 /* Invalidate all TLB of this process. */ 112 /* Invalidate all TLB of this process. */
107 /* Instead of invalidating each TLB, we get new MMU context. */ 113 /* Instead of invalidating each TLB, we get new MMU context. */
108 if (mm->context.id != NO_CONTEXT) { 114 if (cpu_context(cpu, mm) != NO_CONTEXT) {
109 unsigned long flags; 115 unsigned long flags;
110 116
111 local_irq_save(flags); 117 local_irq_save(flags);
112 mm->context.id = NO_CONTEXT; 118 cpu_context(cpu, mm) = NO_CONTEXT;
113 if (mm == current->mm) 119 if (mm == current->mm)
114 activate_context(mm); 120 activate_context(mm, cpu);
115 local_irq_restore(flags); 121 local_irq_restore(flags);
116 } 122 }
117} 123}