diff options
author | David Woodhouse <dwmw2@infradead.org> | 2006-08-30 23:30:38 +0100 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2006-08-30 23:30:38 +0100 |
commit | 0a7d5f8ce960e74fa22986bda4af488539796e49 (patch) | |
tree | e29ad17808a5c3410518e22dae8dfe94801b59f3 /arch/mips/kernel/smp.c | |
parent | 0165508c80a2b5d5268d9c5dfa9b30c534a33693 (diff) | |
parent | dc709bd190c130b299ac19d596594256265c042a (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'arch/mips/kernel/smp.c')
-rw-r--r-- | arch/mips/kernel/smp.c | 35 |
1 files changed, 30 insertions, 5 deletions
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 9096a5ea422..221895802dc 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -319,6 +319,32 @@ static void flush_tlb_mm_ipi(void *mm) } /* + * Special Variant of smp_call_function for use by TLB functions: + * + * o No return value + * o collapses to normal function call on UP kernels + * o collapses to normal function call on systems with a single shared + * primary cache. + * o CONFIG_MIPS_MT_SMTC currently implies there is only one physical core. + */ +static inline void smp_on_other_tlbs(void (*func) (void *info), void *info) +{ +#ifndef CONFIG_MIPS_MT_SMTC + smp_call_function(func, info, 1, 1); +#endif +} + +static inline void smp_on_each_tlb(void (*func) (void *info), void *info) +{ + preempt_disable(); + + smp_on_other_tlbs(func, info); + func(info); + + preempt_enable(); +} + +/* * The following tlb flush calls are invoked when old translations are * being torn down, or pte attributes are changing. For single threaded * address spaces, a new context is obtained on the current cpu, and tlb @@ -336,7 +362,7 @@ void flush_tlb_mm(struct mm_struct *mm) preempt_disable(); if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) { - smp_call_function(flush_tlb_mm_ipi, (void *)mm, 1, 1); + smp_on_other_tlbs(flush_tlb_mm_ipi, (void *)mm); } else { int i; for (i = 0; i < num_online_cpus(); i++) @@ -372,7 +398,7 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned l fd.vma = vma; fd.addr1 = start; fd.addr2 = end; - smp_call_function(flush_tlb_range_ipi, (void *)&fd, 1, 1); + smp_on_other_tlbs(flush_tlb_range_ipi, (void *)&fd); } else { int i; for (i = 0; i < num_online_cpus(); i++) @@ -414,7 +440,7 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) fd.vma = vma; fd.addr1 = page; - smp_call_function(flush_tlb_page_ipi, (void *)&fd, 1, 1); + smp_on_other_tlbs(flush_tlb_page_ipi, (void *)&fd); } else { int i; for (i = 0; i < num_online_cpus(); i++) @@ -434,8 +460,7 @@ static void flush_tlb_one_ipi(void *info) void flush_tlb_one(unsigned long vaddr) { - smp_call_function(flush_tlb_one_ipi, (void *) vaddr, 1, 1); - local_flush_tlb_one(vaddr); + smp_on_each_tlb(flush_tlb_one_ipi, (void *) vaddr); } static DEFINE_PER_CPU(struct cpu, cpu_devices); |