diff options
author | Guillaume Autran <gautran@mrv.com> | 2005-07-13 04:10:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-07-13 14:25:24 -0400 |
commit | ddca3b80cef36cc668f924ef5154a79acb19ebd7 (patch) | |
tree | 2cfb8ac6837682d975a1cb761360977ac54a6aef /include/asm-ppc | |
parent | 88bd5121d635136e01369141367f315665534b3c (diff) |
[PATCH] ppc32: fix destroy_context() race condition
Fix for a race condition when a task gets preempted by another task while
executing the destroy_context(...) in a FEW_CONTEXTS environment.
mm->context == NO_CONTEXT but the context_map may indicate all contexts are
in use.
The solution to this problem is to disable kernel preemption while
destroying a MMU context.
Signed-off-by: Guillaume Autran <gautran@mrv.com>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/asm-ppc')
-rw-r--r-- | include/asm-ppc/mmu_context.h | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/include/asm-ppc/mmu_context.h b/include/asm-ppc/mmu_context.h index ccabbce39d85..afe26ffc2e2d 100644 --- a/include/asm-ppc/mmu_context.h +++ b/include/asm-ppc/mmu_context.h | |||
@@ -149,6 +149,7 @@ static inline void get_mmu_context(struct mm_struct *mm) | |||
149 | */ | 149 | */ |
150 | static inline void destroy_context(struct mm_struct *mm) | 150 | static inline void destroy_context(struct mm_struct *mm) |
151 | { | 151 | { |
152 | preempt_disable(); | ||
152 | if (mm->context != NO_CONTEXT) { | 153 | if (mm->context != NO_CONTEXT) { |
153 | clear_bit(mm->context, context_map); | 154 | clear_bit(mm->context, context_map); |
154 | mm->context = NO_CONTEXT; | 155 | mm->context = NO_CONTEXT; |
@@ -156,6 +157,7 @@ static inline void destroy_context(struct mm_struct *mm) | |||
156 | atomic_inc(&nr_free_contexts); | 157 | atomic_inc(&nr_free_contexts); |
157 | #endif | 158 | #endif |
158 | } | 159 | } |
160 | preempt_enable(); | ||
159 | } | 161 | } |
160 | 162 | ||
161 | static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, | 163 | static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, |