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 | |
| 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>
| -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, |
