diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2010-08-24 03:26:21 -0400 |
---|---|---|
committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2010-08-24 03:26:34 -0400 |
commit | 050eef364ad700590a605a0749f825cab4834b1e (patch) | |
tree | 2714c9cf7edcbf394971cc2c929e5ab2ea34d6a6 /arch/s390/kernel/smp.c | |
parent | 7af048dc7639db5202c56fecf2346c310647a218 (diff) |
[S390] fix tlb flushing vs. concurrent /proc accesses
The tlb flushing code uses the mm_users field of the mm_struct to
decide if each page table entry needs to be flushed individually with
IPTE or if a global flush for the mm_struct is sufficient after all page
table updates have been done. The comment for mm_users says "How many
users with user space?" but the /proc code increases mm_users after it
found the process structure by pid without creating a new user process.
Which makes mm_users useless for the decision between the two tlb
flusing methods. The current code can be confused to not flush tlb
entries by a concurrent access to /proc files if e.g. a fork is in
progres. The solution for this problem is to make the tlb flushing
logic independent from the mm_users field.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/smp.c')
-rw-r--r-- | arch/s390/kernel/smp.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 541053ed234e..8127ebd59c4d 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -583,6 +583,7 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
583 | sf->gprs[9] = (unsigned long) sf; | 583 | sf->gprs[9] = (unsigned long) sf; |
584 | cpu_lowcore->save_area[15] = (unsigned long) sf; | 584 | cpu_lowcore->save_area[15] = (unsigned long) sf; |
585 | __ctl_store(cpu_lowcore->cregs_save_area, 0, 15); | 585 | __ctl_store(cpu_lowcore->cregs_save_area, 0, 15); |
586 | atomic_inc(&init_mm.context.attach_count); | ||
586 | asm volatile( | 587 | asm volatile( |
587 | " stam 0,15,0(%0)" | 588 | " stam 0,15,0(%0)" |
588 | : : "a" (&cpu_lowcore->access_regs_save_area) : "memory"); | 589 | : : "a" (&cpu_lowcore->access_regs_save_area) : "memory"); |
@@ -659,6 +660,7 @@ void __cpu_die(unsigned int cpu) | |||
659 | while (sigp_p(0, cpu, sigp_set_prefix) == sigp_busy) | 660 | while (sigp_p(0, cpu, sigp_set_prefix) == sigp_busy) |
660 | udelay(10); | 661 | udelay(10); |
661 | smp_free_lowcore(cpu); | 662 | smp_free_lowcore(cpu); |
663 | atomic_dec(&init_mm.context.attach_count); | ||
662 | pr_info("Processor %d stopped\n", cpu); | 664 | pr_info("Processor %d stopped\n", cpu); |
663 | } | 665 | } |
664 | 666 | ||