diff options
author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2011-02-24 05:47:32 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2011-03-01 22:56:48 -0500 |
commit | f342552b917a18a7a1fa2c10625df85fac828c36 (patch) | |
tree | 236fc598d5c4342bd69c0098547ad6df51557990 /arch/powerpc | |
parent | dd9c1549edef02290edced639f67b54a25abbe0e (diff) |
powerpc/mm: Make hpte_need_flush() safe for preemption
hpte_need_flush() might be called outside of a preempt section
when manipulating the kernel page tables, so we need to use the
appopriate variants of per-cpu variable accesses. There should
be no risk of being in the middle of a batch and a context
switch will flush any pending batch.
[Patch extracted from a larger patch in Peter's preemptible
mmu_gather series]
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Hugh Dickins <hughd@google.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/mm/tlb_hash64.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/arch/powerpc/mm/tlb_hash64.c b/arch/powerpc/mm/tlb_hash64.c index 1ec06576f619..c14d09f614f3 100644 --- a/arch/powerpc/mm/tlb_hash64.c +++ b/arch/powerpc/mm/tlb_hash64.c | |||
@@ -38,13 +38,11 @@ DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch); | |||
38 | * neesd to be flushed. This function will either perform the flush | 38 | * neesd to be flushed. This function will either perform the flush |
39 | * immediately or will batch it up if the current CPU has an active | 39 | * immediately or will batch it up if the current CPU has an active |
40 | * batch on it. | 40 | * batch on it. |
41 | * | ||
42 | * Must be called from within some kind of spinlock/non-preempt region... | ||
43 | */ | 41 | */ |
44 | void hpte_need_flush(struct mm_struct *mm, unsigned long addr, | 42 | void hpte_need_flush(struct mm_struct *mm, unsigned long addr, |
45 | pte_t *ptep, unsigned long pte, int huge) | 43 | pte_t *ptep, unsigned long pte, int huge) |
46 | { | 44 | { |
47 | struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); | 45 | struct ppc64_tlb_batch *batch = &get_cpu_var(ppc64_tlb_batch); |
48 | unsigned long vsid, vaddr; | 46 | unsigned long vsid, vaddr; |
49 | unsigned int psize; | 47 | unsigned int psize; |
50 | int ssize; | 48 | int ssize; |
@@ -99,6 +97,7 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr, | |||
99 | */ | 97 | */ |
100 | if (!batch->active) { | 98 | if (!batch->active) { |
101 | flush_hash_page(vaddr, rpte, psize, ssize, 0); | 99 | flush_hash_page(vaddr, rpte, psize, ssize, 0); |
100 | put_cpu_var(ppc64_tlb_batch); | ||
102 | return; | 101 | return; |
103 | } | 102 | } |
104 | 103 | ||
@@ -127,6 +126,7 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr, | |||
127 | batch->index = ++i; | 126 | batch->index = ++i; |
128 | if (i >= PPC64_TLB_BATCH_NR) | 127 | if (i >= PPC64_TLB_BATCH_NR) |
129 | __flush_tlb_pending(batch); | 128 | __flush_tlb_pending(batch); |
129 | put_cpu_var(ppc64_tlb_batch); | ||
130 | } | 130 | } |
131 | 131 | ||
132 | /* | 132 | /* |