From: tip-bot for Oleg Nesterov <tipbot@zytor.com>
To: linux-tip-commits@vger.kernel.org
Cc: hpa@zytor.com, torvalds@linux-foundation.org,
akpm@linux-foundation.org, linux-kernel@vger.kernel.org,
cebbert.lkml@gmail.com, fweisbec@gmail.com, oleg@redhat.com,
dvlasenk@redhat.com, mingo@kernel.org, sasha.levin@oracle.com,
masami.hiramatsu.pt@hitachi.com, agraf@suse.de,
luto@amacapital.net, peterz@infradead.org, cl@linux.com,
tglx@linutronix.de, rostedt@goodmis.org
Subject: [tip:sched/core] sched: stop the unbound recursion in preempt_schedule_context()
Date: Tue, 28 Oct 2014 04:03:13 -0700 [thread overview]
Message-ID: <tip-009f60e2763568cdcd75bd1cf360c7c7165e2e60@git.kernel.org> (raw)
In-Reply-To: <20141005202322.GB27962@redhat.com>
Commit-ID: 009f60e2763568cdcd75bd1cf360c7c7165e2e60
Gitweb: http://git.kernel.org/tip/009f60e2763568cdcd75bd1cf360c7c7165e2e60
Author: Oleg Nesterov <oleg@redhat.com>
AuthorDate: Sun, 5 Oct 2014 22:23:22 +0200
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Tue, 28 Oct 2014 10:46:05 +0100
sched: stop the unbound recursion in preempt_schedule_context()
preempt_schedule_context() does preempt_enable_notrace() at the end
and this can call the same function again; exception_exit() is heavy
and it is quite possible that need-resched is true again.
1. Change this code to dec preempt_count() and check need_resched()
by hand.
2. As Linus suggested, we can use the PREEMPT_ACTIVE bit and avoid
the enable/disable dance around __schedule(). But in this case
we need to move into sched/core.c.
3. Cosmetic, but x86 forgets to declare this function. This doesn't
really matter because it is only called by asm helpers, still it
make sense to add the declaration into asm/preempt.h to match
preempt_schedule().
Reported-by: Sasha Levin <sasha.levin@oracle.com>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Alexander Graf <agraf@suse.de>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Christoph Lameter <cl@linux.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Peter Anvin <hpa@zytor.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Chuck Ebbert <cebbert.lkml@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Link: http://lkml.kernel.org/r/20141005202322.GB27962@redhat.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
arch/x86/include/asm/preempt.h | 1 +
kernel/context_tracking.c | 40 ----------------------------------------
kernel/sched/core.c | 41 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 42 insertions(+), 40 deletions(-)
diff --git a/arch/x86/include/asm/preempt.h b/arch/x86/include/asm/preempt.h
index 7024c12..4008734 100644
--- a/arch/x86/include/asm/preempt.h
+++ b/arch/x86/include/asm/preempt.h
@@ -105,6 +105,7 @@ static __always_inline bool should_resched(void)
# ifdef CONFIG_CONTEXT_TRACKING
extern asmlinkage void ___preempt_schedule_context(void);
# define __preempt_schedule_context() asm ("call ___preempt_schedule_context")
+ extern asmlinkage void preempt_schedule_context(void);
# endif
#endif
diff --git a/kernel/context_tracking.c b/kernel/context_tracking.c
index 5664985..937ecdf 100644
--- a/kernel/context_tracking.c
+++ b/kernel/context_tracking.c
@@ -107,46 +107,6 @@ void context_tracking_user_enter(void)
}
NOKPROBE_SYMBOL(context_tracking_user_enter);
-#ifdef CONFIG_PREEMPT
-/**
- * preempt_schedule_context - preempt_schedule called by tracing
- *
- * The tracing infrastructure uses preempt_enable_notrace to prevent
- * recursion and tracing preempt enabling caused by the tracing
- * infrastructure itself. But as tracing can happen in areas coming
- * from userspace or just about to enter userspace, a preempt enable
- * can occur before user_exit() is called. This will cause the scheduler
- * to be called when the system is still in usermode.
- *
- * To prevent this, the preempt_enable_notrace will use this function
- * instead of preempt_schedule() to exit user context if needed before
- * calling the scheduler.
- */
-asmlinkage __visible void __sched notrace preempt_schedule_context(void)
-{
- enum ctx_state prev_ctx;
-
- if (likely(!preemptible()))
- return;
-
- /*
- * Need to disable preemption in case user_exit() is traced
- * and the tracer calls preempt_enable_notrace() causing
- * an infinite recursion.
- */
- preempt_disable_notrace();
- prev_ctx = exception_enter();
- preempt_enable_no_resched_notrace();
-
- preempt_schedule();
-
- preempt_disable_notrace();
- exception_exit(prev_ctx);
- preempt_enable_notrace();
-}
-EXPORT_SYMBOL_GPL(preempt_schedule_context);
-#endif /* CONFIG_PREEMPT */
-
/**
* context_tracking_user_exit - Inform the context tracking that the CPU is
* exiting userspace mode and entering the kernel.
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index dde8adb..240157c 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -2951,6 +2951,47 @@ asmlinkage __visible void __sched notrace preempt_schedule(void)
}
NOKPROBE_SYMBOL(preempt_schedule);
EXPORT_SYMBOL(preempt_schedule);
+
+#ifdef CONFIG_CONTEXT_TRACKING
+/**
+ * preempt_schedule_context - preempt_schedule called by tracing
+ *
+ * The tracing infrastructure uses preempt_enable_notrace to prevent
+ * recursion and tracing preempt enabling caused by the tracing
+ * infrastructure itself. But as tracing can happen in areas coming
+ * from userspace or just about to enter userspace, a preempt enable
+ * can occur before user_exit() is called. This will cause the scheduler
+ * to be called when the system is still in usermode.
+ *
+ * To prevent this, the preempt_enable_notrace will use this function
+ * instead of preempt_schedule() to exit user context if needed before
+ * calling the scheduler.
+ */
+asmlinkage __visible void __sched notrace preempt_schedule_context(void)
+{
+ enum ctx_state prev_ctx;
+
+ if (likely(!preemptible()))
+ return;
+
+ do {
+ __preempt_count_add(PREEMPT_ACTIVE);
+ /*
+ * Needs preempt disabled in case user_exit() is traced
+ * and the tracer calls preempt_enable_notrace() causing
+ * an infinite recursion.
+ */
+ prev_ctx = exception_enter();
+ __schedule();
+ exception_exit(prev_ctx);
+
+ __preempt_count_sub(PREEMPT_ACTIVE);
+ barrier();
+ } while (need_resched());
+}
+EXPORT_SYMBOL_GPL(preempt_schedule_context);
+#endif /* CONFIG_CONTEXT_TRACKING */
+
#endif /* CONFIG_PREEMPT */
/*
next prev parent reply other threads:[~2014-10-28 11:04 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-09-21 18:41 [PATCH v3 0/2] x86: reimplement ___preempt_schedule*() using THUNK helpers Oleg Nesterov
2014-09-21 18:41 ` [PATCH v3 1/2] " Oleg Nesterov
2014-09-24 15:02 ` [tip:x86/asm] x86: Speed up ___preempt_schedule*() by " tip-bot for Oleg Nesterov
2014-10-03 4:50 ` Sasha Levin
2014-10-03 13:39 ` Chuck Ebbert
2014-10-03 21:41 ` Oleg Nesterov
2014-10-03 21:56 ` Andy Lutomirski
2014-10-03 23:48 ` Linus Torvalds
2014-10-03 23:51 ` Oleg Nesterov
2014-10-03 22:48 ` Chuck Ebbert
2014-10-03 22:53 ` Andy Lutomirski
2014-10-03 23:13 ` H. Peter Anvin
2014-10-03 23:37 ` Oleg Nesterov
2014-10-03 21:16 ` Oleg Nesterov
2014-10-03 23:26 ` Oleg Nesterov
2014-10-04 0:01 ` Linus Torvalds
2014-10-04 0:11 ` Linus Torvalds
2014-10-04 0:33 ` Oleg Nesterov
2014-10-05 20:23 ` [PATCH 0/1] stop the unbound recursion in preempt_schedule_context() Oleg Nesterov
2014-10-05 20:23 ` [PATCH 1/1] " Oleg Nesterov
2014-10-28 11:03 ` tip-bot for Oleg Nesterov [this message]
2014-10-05 23:53 ` [PATCH 0/1] " Oleg Nesterov
2014-10-04 0:19 ` [tip:x86/asm] x86: Speed up ___preempt_schedule*() by using THUNK helpers Oleg Nesterov
2014-09-21 18:42 ` [PATCH v3 2/2] x86, lib/Makefile: remove the unnecessary "+= thunk_64.o" Oleg Nesterov
2014-09-24 15:02 ` [tip:x86/asm] x86/lib/Makefile: Remove " tip-bot for Oleg Nesterov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=tip-009f60e2763568cdcd75bd1cf360c7c7165e2e60@git.kernel.org \
--to=tipbot@zytor.com \
--cc=agraf@suse.de \
--cc=akpm@linux-foundation.org \
--cc=cebbert.lkml@gmail.com \
--cc=cl@linux.com \
--cc=dvlasenk@redhat.com \
--cc=fweisbec@gmail.com \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-tip-commits@vger.kernel.org \
--cc=luto@amacapital.net \
--cc=masami.hiramatsu.pt@hitachi.com \
--cc=mingo@kernel.org \
--cc=oleg@redhat.com \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
--cc=sasha.levin@oracle.com \
--cc=tglx@linutronix.de \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).