diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2016-05-25 03:45:26 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2016-06-13 09:58:22 -0400 |
commit | 64f31d5802af11fd87872b4bae07b35cf0acb358 (patch) | |
tree | 73f514c73762092fd6710efa6863a5a6124d86a3 /arch/s390/mm | |
parent | 7dd968163f7c12bcb2132792bf873133b397a2d2 (diff) |
s390/mm: simplify the TLB flushing code
ptep_flush_lazy and pmdp_flush_lazy use mm->context.attach_count to
decide between a lazy TLB flush vs an immediate TLB flush. The field
contains two 16-bit counters, the number of CPUs that have the mm
attached and can create TLB entries for it and the number of CPUs in
the middle of a page table update.
The __tlb_flush_asce, ptep_flush_direct and pmdp_flush_direct functions
use the attach counter and a mask check with mm_cpumask(mm) to decide
between a local flush local of the current CPU and a global flush.
For all these functions the decision between lazy vs immediate and
local vs global TLB flush can be based on CPU masks. There are two
masks: the mm->context.cpu_attach_mask with the CPUs that are actively
using the mm, and the mm_cpumask(mm) with the CPUs that have used the
mm since the last full flush. The decision between lazy vs immediate
flush is based on the mm->context.cpu_attach_mask, to decide between
local vs global flush the mm_cpumask(mm) is used.
With this patch all checks will use the CPU masks, the old counter
mm->context.attach_count with its two 16-bit values is turned into a
single counter mm->context.flush_count that keeps track of the number
of CPUs with incomplete page table updates. The sole user of this
counter is finish_arch_post_lock_switch() which waits for the end of
all page table updates.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/mm')
-rw-r--r-- | arch/s390/mm/init.c | 4 | ||||
-rw-r--r-- | arch/s390/mm/pgtable.c | 34 |
2 files changed, 15 insertions, 23 deletions
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index 44db60d9e519..de2cdf4fbb9a 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c | |||
@@ -118,10 +118,8 @@ void mark_rodata_ro(void) | |||
118 | 118 | ||
119 | void __init mem_init(void) | 119 | void __init mem_init(void) |
120 | { | 120 | { |
121 | if (MACHINE_HAS_TLB_LC) | 121 | cpumask_set_cpu(0, &init_mm.context.cpu_attach_mask); |
122 | cpumask_set_cpu(0, &init_mm.context.cpu_attach_mask); | ||
123 | cpumask_set_cpu(0, mm_cpumask(&init_mm)); | 122 | cpumask_set_cpu(0, mm_cpumask(&init_mm)); |
124 | atomic_set(&init_mm.context.attach_count, 1); | ||
125 | 123 | ||
126 | set_max_mapnr(max_low_pfn); | 124 | set_max_mapnr(max_low_pfn); |
127 | high_memory = (void *) __va(max_low_pfn * PAGE_SIZE); | 125 | high_memory = (void *) __va(max_low_pfn * PAGE_SIZE); |
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 67111ccbb5e0..74f8f2a8a4e8 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c | |||
@@ -27,40 +27,37 @@ | |||
27 | static inline pte_t ptep_flush_direct(struct mm_struct *mm, | 27 | static inline pte_t ptep_flush_direct(struct mm_struct *mm, |
28 | unsigned long addr, pte_t *ptep) | 28 | unsigned long addr, pte_t *ptep) |
29 | { | 29 | { |
30 | int active, count; | ||
31 | pte_t old; | 30 | pte_t old; |
32 | 31 | ||
33 | old = *ptep; | 32 | old = *ptep; |
34 | if (unlikely(pte_val(old) & _PAGE_INVALID)) | 33 | if (unlikely(pte_val(old) & _PAGE_INVALID)) |
35 | return old; | 34 | return old; |
36 | active = (mm == current->active_mm) ? 1 : 0; | 35 | atomic_inc(&mm->context.flush_count); |
37 | count = atomic_add_return(0x10000, &mm->context.attach_count); | 36 | if (MACHINE_HAS_TLB_LC && |
38 | if (MACHINE_HAS_TLB_LC && (count & 0xffff) <= active && | ||
39 | cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) | 37 | cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) |
40 | __ptep_ipte_local(addr, ptep); | 38 | __ptep_ipte_local(addr, ptep); |
41 | else | 39 | else |
42 | __ptep_ipte(addr, ptep); | 40 | __ptep_ipte(addr, ptep); |
43 | atomic_sub(0x10000, &mm->context.attach_count); | 41 | atomic_dec(&mm->context.flush_count); |
44 | return old; | 42 | return old; |
45 | } | 43 | } |
46 | 44 | ||
47 | static inline pte_t ptep_flush_lazy(struct mm_struct *mm, | 45 | static inline pte_t ptep_flush_lazy(struct mm_struct *mm, |
48 | unsigned long addr, pte_t *ptep) | 46 | unsigned long addr, pte_t *ptep) |
49 | { | 47 | { |
50 | int active, count; | ||
51 | pte_t old; | 48 | pte_t old; |
52 | 49 | ||
53 | old = *ptep; | 50 | old = *ptep; |
54 | if (unlikely(pte_val(old) & _PAGE_INVALID)) | 51 | if (unlikely(pte_val(old) & _PAGE_INVALID)) |
55 | return old; | 52 | return old; |
56 | active = (mm == current->active_mm) ? 1 : 0; | 53 | atomic_inc(&mm->context.flush_count); |
57 | count = atomic_add_return(0x10000, &mm->context.attach_count); | 54 | if (cpumask_equal(&mm->context.cpu_attach_mask, |
58 | if ((count & 0xffff) <= active) { | 55 | cpumask_of(smp_processor_id()))) { |
59 | pte_val(*ptep) |= _PAGE_INVALID; | 56 | pte_val(*ptep) |= _PAGE_INVALID; |
60 | mm->context.flush_mm = 1; | 57 | mm->context.flush_mm = 1; |
61 | } else | 58 | } else |
62 | __ptep_ipte(addr, ptep); | 59 | __ptep_ipte(addr, ptep); |
63 | atomic_sub(0x10000, &mm->context.attach_count); | 60 | atomic_dec(&mm->context.flush_count); |
64 | return old; | 61 | return old; |
65 | } | 62 | } |
66 | 63 | ||
@@ -289,7 +286,6 @@ EXPORT_SYMBOL(ptep_modify_prot_commit); | |||
289 | static inline pmd_t pmdp_flush_direct(struct mm_struct *mm, | 286 | static inline pmd_t pmdp_flush_direct(struct mm_struct *mm, |
290 | unsigned long addr, pmd_t *pmdp) | 287 | unsigned long addr, pmd_t *pmdp) |
291 | { | 288 | { |
292 | int active, count; | ||
293 | pmd_t old; | 289 | pmd_t old; |
294 | 290 | ||
295 | old = *pmdp; | 291 | old = *pmdp; |
@@ -299,36 +295,34 @@ static inline pmd_t pmdp_flush_direct(struct mm_struct *mm, | |||
299 | __pmdp_csp(pmdp); | 295 | __pmdp_csp(pmdp); |
300 | return old; | 296 | return old; |
301 | } | 297 | } |
302 | active = (mm == current->active_mm) ? 1 : 0; | 298 | atomic_inc(&mm->context.flush_count); |
303 | count = atomic_add_return(0x10000, &mm->context.attach_count); | 299 | if (MACHINE_HAS_TLB_LC && |
304 | if (MACHINE_HAS_TLB_LC && (count & 0xffff) <= active && | ||
305 | cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) | 300 | cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) |
306 | __pmdp_idte_local(addr, pmdp); | 301 | __pmdp_idte_local(addr, pmdp); |
307 | else | 302 | else |
308 | __pmdp_idte(addr, pmdp); | 303 | __pmdp_idte(addr, pmdp); |
309 | atomic_sub(0x10000, &mm->context.attach_count); | 304 | atomic_dec(&mm->context.flush_count); |
310 | return old; | 305 | return old; |
311 | } | 306 | } |
312 | 307 | ||
313 | static inline pmd_t pmdp_flush_lazy(struct mm_struct *mm, | 308 | static inline pmd_t pmdp_flush_lazy(struct mm_struct *mm, |
314 | unsigned long addr, pmd_t *pmdp) | 309 | unsigned long addr, pmd_t *pmdp) |
315 | { | 310 | { |
316 | int active, count; | ||
317 | pmd_t old; | 311 | pmd_t old; |
318 | 312 | ||
319 | old = *pmdp; | 313 | old = *pmdp; |
320 | if (pmd_val(old) & _SEGMENT_ENTRY_INVALID) | 314 | if (pmd_val(old) & _SEGMENT_ENTRY_INVALID) |
321 | return old; | 315 | return old; |
322 | active = (mm == current->active_mm) ? 1 : 0; | 316 | atomic_inc(&mm->context.flush_count); |
323 | count = atomic_add_return(0x10000, &mm->context.attach_count); | 317 | if (cpumask_equal(&mm->context.cpu_attach_mask, |
324 | if ((count & 0xffff) <= active) { | 318 | cpumask_of(smp_processor_id()))) { |
325 | pmd_val(*pmdp) |= _SEGMENT_ENTRY_INVALID; | 319 | pmd_val(*pmdp) |= _SEGMENT_ENTRY_INVALID; |
326 | mm->context.flush_mm = 1; | 320 | mm->context.flush_mm = 1; |
327 | } else if (MACHINE_HAS_IDTE) | 321 | } else if (MACHINE_HAS_IDTE) |
328 | __pmdp_idte(addr, pmdp); | 322 | __pmdp_idte(addr, pmdp); |
329 | else | 323 | else |
330 | __pmdp_csp(pmdp); | 324 | __pmdp_csp(pmdp); |
331 | atomic_sub(0x10000, &mm->context.attach_count); | 325 | atomic_dec(&mm->context.flush_count); |
332 | return old; | 326 | return old; |
333 | } | 327 | } |
334 | 328 | ||