diff options
Diffstat (limited to 'arch')
-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 9096a5ea4229..221895802dca 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) | |||
319 | } | 319 | } |
320 | 320 | ||
321 | /* | 321 | /* |
322 | * Special Variant of smp_call_function for use by TLB functions: | ||
323 | * | ||
324 | * o No return value | ||
325 | * o collapses to normal function call on UP kernels | ||
326 | * o collapses to normal function call on systems with a single shared | ||
327 | * primary cache. | ||
328 | * o CONFIG_MIPS_MT_SMTC currently implies there is only one physical core. | ||
329 | */ | ||
330 | static inline void smp_on_other_tlbs(void (*func) (void *info), void *info) | ||
331 | { | ||
332 | #ifndef CONFIG_MIPS_MT_SMTC | ||
333 | smp_call_function(func, info, 1, 1); | ||
334 | #endif | ||
335 | } | ||
336 | |||
337 | static inline void smp_on_each_tlb(void (*func) (void *info), void *info) | ||
338 | { | ||
339 | preempt_disable(); | ||
340 | |||
341 | smp_on_other_tlbs(func, info); | ||
342 | func(info); | ||
343 | |||
344 | preempt_enable(); | ||
345 | } | ||
346 | |||
347 | /* | ||
322 | * The following tlb flush calls are invoked when old translations are | 348 | * The following tlb flush calls are invoked when old translations are |
323 | * being torn down, or pte attributes are changing. For single threaded | 349 | * being torn down, or pte attributes are changing. For single threaded |
324 | * address spaces, a new context is obtained on the current cpu, and tlb | 350 | * 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) | |||
336 | preempt_disable(); | 362 | preempt_disable(); |
337 | 363 | ||
338 | if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) { | 364 | if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) { |
339 | smp_call_function(flush_tlb_mm_ipi, (void *)mm, 1, 1); | 365 | smp_on_other_tlbs(flush_tlb_mm_ipi, (void *)mm); |
340 | } else { | 366 | } else { |
341 | int i; | 367 | int i; |
342 | for (i = 0; i < num_online_cpus(); i++) | 368 | 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 | |||
372 | fd.vma = vma; | 398 | fd.vma = vma; |
373 | fd.addr1 = start; | 399 | fd.addr1 = start; |
374 | fd.addr2 = end; | 400 | fd.addr2 = end; |
375 | smp_call_function(flush_tlb_range_ipi, (void *)&fd, 1, 1); | 401 | smp_on_other_tlbs(flush_tlb_range_ipi, (void *)&fd); |
376 | } else { | 402 | } else { |
377 | int i; | 403 | int i; |
378 | for (i = 0; i < num_online_cpus(); i++) | 404 | for (i = 0; i < num_online_cpus(); i++) |
@@ -414,7 +440,7 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) | |||
414 | 440 | ||
415 | fd.vma = vma; | 441 | fd.vma = vma; |
416 | fd.addr1 = page; | 442 | fd.addr1 = page; |
417 | smp_call_function(flush_tlb_page_ipi, (void *)&fd, 1, 1); | 443 | smp_on_other_tlbs(flush_tlb_page_ipi, (void *)&fd); |
418 | } else { | 444 | } else { |
419 | int i; | 445 | int i; |
420 | for (i = 0; i < num_online_cpus(); i++) | 446 | for (i = 0; i < num_online_cpus(); i++) |
@@ -434,8 +460,7 @@ static void flush_tlb_one_ipi(void *info) | |||
434 | 460 | ||
435 | void flush_tlb_one(unsigned long vaddr) | 461 | void flush_tlb_one(unsigned long vaddr) |
436 | { | 462 | { |
437 | smp_call_function(flush_tlb_one_ipi, (void *) vaddr, 1, 1); | 463 | smp_on_each_tlb(flush_tlb_one_ipi, (void *) vaddr); |
438 | local_flush_tlb_one(vaddr); | ||
439 | } | 464 | } |
440 | 465 | ||
441 | static DEFINE_PER_CPU(struct cpu, cpu_devices); | 466 | static DEFINE_PER_CPU(struct cpu, cpu_devices); |