ppc32: fix destroy_context() race condition
PATCH 1/1 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.
---
include/asm-ppc/mmu_context.h +0 -0
@@ -149,6 +149,7 @@
*/
static inline void destroy_context(struct mm_struct *mm) {
+ preempt_disable();
if (mm->context != NO_CONTEXT) {
clear_bit(mm->context, context_map);
mm->context = NO_CONTEXT;
@@ -156,6 +157,7 @@
atomic_inc(&nr_free_contexts);
#endif
}+ preempt_enable();
}
static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
Quoted 24 lines · Guillaume Autran
Fix for a race condition when a task gets preempted by another task while executing the
destroy_context(...)in aFEW_CONTEXTSenvironment.mm->context==NO_CONTEXTbut thecontext_mapmay 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 <[email protected]>---
diff -Nru
a/include/asm-ppc/mmu_context.hb/include/asm-ppc/mmu_context.hinclude/asm-ppc/mmu_context.h +1
-0@@ -149,6 +149,7 @@*/ static inline void destroy_context (struct mm_struct *mm) { +preempt_disable ();if (mm->context !=NO_CONTEXT ) {clear_bit (mm->context, context_map); mm->context =NO_CONTEXT ;
include/asm-ppc/mmu_context.h line 163
Quoted 7 lines
include/asm-ppc/mmu_context.h +1
-0@@ -156,6 +157,7 @@atomic_inc (&nr_free_contexts);#endif } +preempt_enable (); } static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
Could you explain, why this patch is needed?
AFAIK, destroy_context() is only called from switch_mm(), which in turn is called from schedule() with preemption already disabled. If not, IMHO we have bigger problems, and "fixing" destroy_context() will only hide such problems.
Signature · 1 line
Eugene
Eugene, destroy_context(..) can be called from other place outside of the scheduler and switch_mm(...). See mmdrop(...) for example. In many of those cases, the task will run with preemption enable.
Guillaume.
Quoted 43 lines · Eugene Surovegin
Quoted 26 lines · Guillaume Autran
Fix for a race condition when a task gets preempted by another task while executing the
destroy_context(...)in aFEW_CONTEXTSenvironment.mm->context==NO_CONTEXTbut thecontext_mapmay 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 <[email protected]>---
diff -Nru
a/include/asm-ppc/mmu_context.hb/include/asm-ppc/mmu_context.hinclude/asm-ppc/mmu_context.h +1
-0@@ -149,6 +149,7 @@*/ static inline void destroy_context (struct mm_struct *mm) { +preempt_disable ();if (mm->context !=NO_CONTEXT ) {clear_bit (mm->context, context_map); mm->context =NO_CONTEXT ;include/asm-ppc/mmu_context.h line 163
Quoted 7 lines
include/asm-ppc/mmu_context.h +1
-0@@ -156,6 +157,7 @@atomic_inc (&nr_free_contexts);#endif } +preempt_enable (); } static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,Could you explain, why this patch is needed?
AFAIK,
destroy_context()is only called fromswitch_mm(), which in turn is called fromschedule()with preemption already disabled. If not, IMHO we have bigger problems, and "fixing"destroy_context()will only hide such problems.
Signature · 7 lines
======================================= Guillaume Autran Senior Software Engineer MRV Communications, Inc. Tel: (978) 952-4932 office E-mail: [email protected] =======================================
Quoted 3 lines · Guillaume Autran
Eugene,
destroy_context(..)can be called from other place outside of the scheduler andswitch_mm(...). See mmdrop(...) for example. In many of those cases, the task will run with preemption enable.
Ahh, OK, you're right. Maybe it's worth mentioning in the patch description :).
Signature · 1 line
Eugene
Quoted 8 lines · Guillaume Autran
Fix for a race condition when a task gets preempted by another task while executing the
destroy_context(...)in aFEW_CONTEXTSenvironment.mm->context==NO_CONTEXTbut thecontext_mapmay 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 <[email protected]>
Quoted 27 lines
---
diff -Nru
a/include/asm-ppc/mmu_context.hb/include/asm-ppc/mmu_context.hinclude/asm-ppc/mmu_context.h +2
-0@@ -149,6 +149,7 @@*/ static inline void destroy_context (struct mm_struct *mm) { +preempt_disable ();if (mm->context !=NO_CONTEXT ) {clear_bit (mm->context, context_map); mm->context =NO_CONTEXT ;@@ -156,6 +157,7 @@atomic_inc (&nr_free_contexts);#endif } +preempt_enable (); } static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,