diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2013-10-27 05:19:02 -0400 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2013-11-06 00:11:45 -0500 |
commit | 5ea72a90261552ed5fdca35239feb6cba498301e (patch) | |
tree | c83f798813ae867ec10c35be6d2f9c3bc99609b5 /arch/arc/mm/tlb.c | |
parent | 63eca94ca206e342bad4a06a86d8e7eda3053a4e (diff) |
ARC: [SMP] TLB flush
- Add mm_cpumask setting (aggregating only, unlike some other arches)
used to restrict the TLB flush cross-calling
- cross-calling versions of TLB flush routines (thanks to Noam)
Signed-off-by: Noam Camus <noamc@ezchip.com>
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Diffstat (limited to 'arch/arc/mm/tlb.c')
-rw-r--r-- | arch/arc/mm/tlb.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c index db0f0f823980..e1acf0ce5647 100644 --- a/arch/arc/mm/tlb.c +++ b/arch/arc/mm/tlb.c | |||
@@ -363,6 +363,79 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) | |||
363 | local_irq_restore(flags); | 363 | local_irq_restore(flags); |
364 | } | 364 | } |
365 | 365 | ||
366 | #ifdef CONFIG_SMP | ||
367 | |||
368 | struct tlb_args { | ||
369 | struct vm_area_struct *ta_vma; | ||
370 | unsigned long ta_start; | ||
371 | unsigned long ta_end; | ||
372 | }; | ||
373 | |||
374 | static inline void ipi_flush_tlb_page(void *arg) | ||
375 | { | ||
376 | struct tlb_args *ta = arg; | ||
377 | |||
378 | local_flush_tlb_page(ta->ta_vma, ta->ta_start); | ||
379 | } | ||
380 | |||
381 | static inline void ipi_flush_tlb_range(void *arg) | ||
382 | { | ||
383 | struct tlb_args *ta = arg; | ||
384 | |||
385 | local_flush_tlb_range(ta->ta_vma, ta->ta_start, ta->ta_end); | ||
386 | } | ||
387 | |||
388 | static inline void ipi_flush_tlb_kernel_range(void *arg) | ||
389 | { | ||
390 | struct tlb_args *ta = (struct tlb_args *)arg; | ||
391 | |||
392 | local_flush_tlb_kernel_range(ta->ta_start, ta->ta_end); | ||
393 | } | ||
394 | |||
395 | void flush_tlb_all(void) | ||
396 | { | ||
397 | on_each_cpu((smp_call_func_t)local_flush_tlb_all, NULL, 1); | ||
398 | } | ||
399 | |||
400 | void flush_tlb_mm(struct mm_struct *mm) | ||
401 | { | ||
402 | on_each_cpu_mask(mm_cpumask(mm), (smp_call_func_t)local_flush_tlb_mm, | ||
403 | mm, 1); | ||
404 | } | ||
405 | |||
406 | void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) | ||
407 | { | ||
408 | struct tlb_args ta = { | ||
409 | .ta_vma = vma, | ||
410 | .ta_start = uaddr | ||
411 | }; | ||
412 | |||
413 | on_each_cpu_mask(mm_cpumask(vma->vm_mm), ipi_flush_tlb_page, &ta, 1); | ||
414 | } | ||
415 | |||
416 | void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | ||
417 | unsigned long end) | ||
418 | { | ||
419 | struct tlb_args ta = { | ||
420 | .ta_vma = vma, | ||
421 | .ta_start = start, | ||
422 | .ta_end = end | ||
423 | }; | ||
424 | |||
425 | on_each_cpu_mask(mm_cpumask(vma->vm_mm), ipi_flush_tlb_range, &ta, 1); | ||
426 | } | ||
427 | |||
428 | void flush_tlb_kernel_range(unsigned long start, unsigned long end) | ||
429 | { | ||
430 | struct tlb_args ta = { | ||
431 | .ta_start = start, | ||
432 | .ta_end = end | ||
433 | }; | ||
434 | |||
435 | on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1); | ||
436 | } | ||
437 | #endif | ||
438 | |||
366 | /* | 439 | /* |
367 | * Routine to create a TLB entry | 440 | * Routine to create a TLB entry |
368 | */ | 441 | */ |