From: Andy Lutomirski Date: Wed, 3 Dec 2014 23:37:08 +0000 (-0800) Subject: context_tracking: Restore previous state in schedule_user X-Git-Tag: firefly_0821_release~176^2~2793 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=7cc78f8fa02c2485104b86434acbc1538a3bd807;p=firefly-linux-kernel-4.4.55.git context_tracking: Restore previous state in schedule_user It appears that some SCHEDULE_USER (asm for schedule_user) callers in arch/x86/kernel/entry_64.S are called from RCU kernel context, and schedule_user will return in RCU user context. This causes RCU warnings and possible failures. This is intended to be a minimal fix suitable for 3.18. Reported-and-tested-by: Dave Jones Cc: Oleg Nesterov Cc: Frédéric Weisbecker Acked-by: Paul E. McKenney Signed-off-by: Andy Lutomirski Signed-off-by: Linus Torvalds --- diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 24beb9bb4c3e..89e7283015a6 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -2874,10 +2874,14 @@ asmlinkage __visible void __sched schedule_user(void) * or we have been woken up remotely but the IPI has not yet arrived, * we haven't yet exited the RCU idle mode. Do it here manually until * we find a better solution. + * + * NB: There are buggy callers of this function. Ideally we + * should warn if prev_state != IN_USER, but that will trigger + * too frequently to make sense yet. */ - user_exit(); + enum ctx_state prev_state = exception_enter(); schedule(); - user_enter(); + exception_exit(prev_state); } #endif