Commit 03b505eae6a276b8c38b6222694afb6cea10b1cc

Authored by Russell King
1 parent 10034aabca

ARM: SMP: split out software TLB maintainence broadcasting

smp.c is becoming too large, so split out the TLB maintainence
broadcasting into a separate smp_tlb.c file.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

Showing 3 changed files with 140 additions and 127 deletions Side-by-side Diff

arch/arm/kernel/Makefile
... ... @@ -29,7 +29,7 @@
29 29 obj-$(CONFIG_ARTHUR) += arthur.o
30 30 obj-$(CONFIG_ISA_DMA) += dma-isa.o
31 31 obj-$(CONFIG_PCI) += bios32.o isa.o
32   -obj-$(CONFIG_SMP) += smp.o
  32 +obj-$(CONFIG_SMP) += smp.o smp_tlb.o
33 33 obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o
34 34 obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o
35 35 obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
arch/arm/kernel/smp.c
... ... @@ -38,7 +38,6 @@
38 38 #include <asm/tlbflush.h>
39 39 #include <asm/ptrace.h>
40 40 #include <asm/localtimer.h>
41   -#include <asm/smp_plat.h>
42 41  
43 42 /*
44 43 * as from 2.5, kernels no longer have an init_tasks structure
... ... @@ -654,130 +653,5 @@
654 653 int setup_profiling_timer(unsigned int multiplier)
655 654 {
656 655 return -EINVAL;
657   -}
658   -
659   -static void
660   -on_each_cpu_mask(void (*func)(void *), void *info, int wait,
661   - const struct cpumask *mask)
662   -{
663   - preempt_disable();
664   -
665   - smp_call_function_many(mask, func, info, wait);
666   - if (cpumask_test_cpu(smp_processor_id(), mask))
667   - func(info);
668   -
669   - preempt_enable();
670   -}
671   -
672   -/**********************************************************************/
673   -
674   -/*
675   - * TLB operations
676   - */
677   -struct tlb_args {
678   - struct vm_area_struct *ta_vma;
679   - unsigned long ta_start;
680   - unsigned long ta_end;
681   -};
682   -
683   -static inline void ipi_flush_tlb_all(void *ignored)
684   -{
685   - local_flush_tlb_all();
686   -}
687   -
688   -static inline void ipi_flush_tlb_mm(void *arg)
689   -{
690   - struct mm_struct *mm = (struct mm_struct *)arg;
691   -
692   - local_flush_tlb_mm(mm);
693   -}
694   -
695   -static inline void ipi_flush_tlb_page(void *arg)
696   -{
697   - struct tlb_args *ta = (struct tlb_args *)arg;
698   -
699   - local_flush_tlb_page(ta->ta_vma, ta->ta_start);
700   -}
701   -
702   -static inline void ipi_flush_tlb_kernel_page(void *arg)
703   -{
704   - struct tlb_args *ta = (struct tlb_args *)arg;
705   -
706   - local_flush_tlb_kernel_page(ta->ta_start);
707   -}
708   -
709   -static inline void ipi_flush_tlb_range(void *arg)
710   -{
711   - struct tlb_args *ta = (struct tlb_args *)arg;
712   -
713   - local_flush_tlb_range(ta->ta_vma, ta->ta_start, ta->ta_end);
714   -}
715   -
716   -static inline void ipi_flush_tlb_kernel_range(void *arg)
717   -{
718   - struct tlb_args *ta = (struct tlb_args *)arg;
719   -
720   - local_flush_tlb_kernel_range(ta->ta_start, ta->ta_end);
721   -}
722   -
723   -void flush_tlb_all(void)
724   -{
725   - if (tlb_ops_need_broadcast())
726   - on_each_cpu(ipi_flush_tlb_all, NULL, 1);
727   - else
728   - local_flush_tlb_all();
729   -}
730   -
731   -void flush_tlb_mm(struct mm_struct *mm)
732   -{
733   - if (tlb_ops_need_broadcast())
734   - on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, mm_cpumask(mm));
735   - else
736   - local_flush_tlb_mm(mm);
737   -}
738   -
739   -void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
740   -{
741   - if (tlb_ops_need_broadcast()) {
742   - struct tlb_args ta;
743   - ta.ta_vma = vma;
744   - ta.ta_start = uaddr;
745   - on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, mm_cpumask(vma->vm_mm));
746   - } else
747   - local_flush_tlb_page(vma, uaddr);
748   -}
749   -
750   -void flush_tlb_kernel_page(unsigned long kaddr)
751   -{
752   - if (tlb_ops_need_broadcast()) {
753   - struct tlb_args ta;
754   - ta.ta_start = kaddr;
755   - on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1);
756   - } else
757   - local_flush_tlb_kernel_page(kaddr);
758   -}
759   -
760   -void flush_tlb_range(struct vm_area_struct *vma,
761   - unsigned long start, unsigned long end)
762   -{
763   - if (tlb_ops_need_broadcast()) {
764   - struct tlb_args ta;
765   - ta.ta_vma = vma;
766   - ta.ta_start = start;
767   - ta.ta_end = end;
768   - on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, mm_cpumask(vma->vm_mm));
769   - } else
770   - local_flush_tlb_range(vma, start, end);
771   -}
772   -
773   -void flush_tlb_kernel_range(unsigned long start, unsigned long end)
774   -{
775   - if (tlb_ops_need_broadcast()) {
776   - struct tlb_args ta;
777   - ta.ta_start = start;
778   - ta.ta_end = end;
779   - on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1);
780   - } else
781   - local_flush_tlb_kernel_range(start, end);
782 656 }
arch/arm/kernel/smp_tlb.c
  1 +/*
  2 + * linux/arch/arm/kernel/smp_tlb.c
  3 + *
  4 + * Copyright (C) 2002 ARM Limited, All Rights Reserved.
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify
  7 + * it under the terms of the GNU General Public License version 2 as
  8 + * published by the Free Software Foundation.
  9 + */
  10 +#include <linux/preempt.h>
  11 +#include <linux/smp.h>
  12 +
  13 +#include <asm/smp_plat.h>
  14 +#include <asm/tlbflush.h>
  15 +
  16 +static void on_each_cpu_mask(void (*func)(void *), void *info, int wait,
  17 + const struct cpumask *mask)
  18 +{
  19 + preempt_disable();
  20 +
  21 + smp_call_function_many(mask, func, info, wait);
  22 + if (cpumask_test_cpu(smp_processor_id(), mask))
  23 + func(info);
  24 +
  25 + preempt_enable();
  26 +}
  27 +
  28 +/**********************************************************************/
  29 +
  30 +/*
  31 + * TLB operations
  32 + */
  33 +struct tlb_args {
  34 + struct vm_area_struct *ta_vma;
  35 + unsigned long ta_start;
  36 + unsigned long ta_end;
  37 +};
  38 +
  39 +static inline void ipi_flush_tlb_all(void *ignored)
  40 +{
  41 + local_flush_tlb_all();
  42 +}
  43 +
  44 +static inline void ipi_flush_tlb_mm(void *arg)
  45 +{
  46 + struct mm_struct *mm = (struct mm_struct *)arg;
  47 +
  48 + local_flush_tlb_mm(mm);
  49 +}
  50 +
  51 +static inline void ipi_flush_tlb_page(void *arg)
  52 +{
  53 + struct tlb_args *ta = (struct tlb_args *)arg;
  54 +
  55 + local_flush_tlb_page(ta->ta_vma, ta->ta_start);
  56 +}
  57 +
  58 +static inline void ipi_flush_tlb_kernel_page(void *arg)
  59 +{
  60 + struct tlb_args *ta = (struct tlb_args *)arg;
  61 +
  62 + local_flush_tlb_kernel_page(ta->ta_start);
  63 +}
  64 +
  65 +static inline void ipi_flush_tlb_range(void *arg)
  66 +{
  67 + struct tlb_args *ta = (struct tlb_args *)arg;
  68 +
  69 + local_flush_tlb_range(ta->ta_vma, ta->ta_start, ta->ta_end);
  70 +}
  71 +
  72 +static inline void ipi_flush_tlb_kernel_range(void *arg)
  73 +{
  74 + struct tlb_args *ta = (struct tlb_args *)arg;
  75 +
  76 + local_flush_tlb_kernel_range(ta->ta_start, ta->ta_end);
  77 +}
  78 +
  79 +void flush_tlb_all(void)
  80 +{
  81 + if (tlb_ops_need_broadcast())
  82 + on_each_cpu(ipi_flush_tlb_all, NULL, 1);
  83 + else
  84 + local_flush_tlb_all();
  85 +}
  86 +
  87 +void flush_tlb_mm(struct mm_struct *mm)
  88 +{
  89 + if (tlb_ops_need_broadcast())
  90 + on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, mm_cpumask(mm));
  91 + else
  92 + local_flush_tlb_mm(mm);
  93 +}
  94 +
  95 +void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
  96 +{
  97 + if (tlb_ops_need_broadcast()) {
  98 + struct tlb_args ta;
  99 + ta.ta_vma = vma;
  100 + ta.ta_start = uaddr;
  101 + on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, mm_cpumask(vma->vm_mm));
  102 + } else
  103 + local_flush_tlb_page(vma, uaddr);
  104 +}
  105 +
  106 +void flush_tlb_kernel_page(unsigned long kaddr)
  107 +{
  108 + if (tlb_ops_need_broadcast()) {
  109 + struct tlb_args ta;
  110 + ta.ta_start = kaddr;
  111 + on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1);
  112 + } else
  113 + local_flush_tlb_kernel_page(kaddr);
  114 +}
  115 +
  116 +void flush_tlb_range(struct vm_area_struct *vma,
  117 + unsigned long start, unsigned long end)
  118 +{
  119 + if (tlb_ops_need_broadcast()) {
  120 + struct tlb_args ta;
  121 + ta.ta_vma = vma;
  122 + ta.ta_start = start;
  123 + ta.ta_end = end;
  124 + on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, mm_cpumask(vma->vm_mm));
  125 + } else
  126 + local_flush_tlb_range(vma, start, end);
  127 +}
  128 +
  129 +void flush_tlb_kernel_range(unsigned long start, unsigned long end)
  130 +{
  131 + if (tlb_ops_need_broadcast()) {
  132 + struct tlb_args ta;
  133 + ta.ta_start = start;
  134 + ta.ta_end = end;
  135 + on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1);
  136 + } else
  137 + local_flush_tlb_kernel_range(start, end);
  138 +}