| From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
| Date: Wed, 20 Jan 2016 15:13:30 +0100 |
| Subject: preempt-lazy: Add the lazy-preemption check to preempt_schedule() |
| |
| Probably in the rebase onto v4.1 this check got moved into less commonly used |
| preempt_schedule_notrace(). This patch ensures that both functions use it. |
| |
| Reported-by: Mike Galbraith <umgwanakikbuti@gmail.com> |
| Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
| --- |
| kernel/sched/core.c | 36 ++++++++++++++++++++++++++++-------- |
| 1 file changed, 28 insertions(+), 8 deletions(-) |
| |
| --- a/kernel/sched/core.c |
| +++ b/kernel/sched/core.c |
| @@ -3501,6 +3501,30 @@ static void __sched notrace preempt_sche |
| } while (need_resched()); |
| } |
| |
| +#ifdef CONFIG_PREEMPT_LAZY |
| +/* |
| + * If TIF_NEED_RESCHED is then we allow to be scheduled away since this is |
| + * set by a RT task. Oterwise we try to avoid beeing scheduled out as long as |
| + * preempt_lazy_count counter >0. |
| + */ |
| +static __always_inline int preemptible_lazy(void) |
| +{ |
| + if (test_thread_flag(TIF_NEED_RESCHED)) |
| + return 1; |
| + if (current_thread_info()->preempt_lazy_count) |
| + return 0; |
| + return 1; |
| +} |
| + |
| +#else |
| + |
| +static int preemptible_lazy(void) |
| +{ |
| + return 1; |
| +} |
| + |
| +#endif |
| + |
| #ifdef CONFIG_PREEMPT |
| /* |
| * this is the entry point to schedule() from in-kernel preemption |
| @@ -3515,6 +3539,8 @@ asmlinkage __visible void __sched notrac |
| */ |
| if (likely(!preemptible())) |
| return; |
| + if (!preemptible_lazy()) |
| + return; |
| |
| preempt_schedule_common(); |
| } |
| @@ -3541,15 +3567,9 @@ asmlinkage __visible void __sched notrac |
| |
| if (likely(!preemptible())) |
| return; |
| - |
| -#ifdef CONFIG_PREEMPT_LAZY |
| - /* |
| - * Check for lazy preemption |
| - */ |
| - if (current_thread_info()->preempt_lazy_count && |
| - !test_thread_flag(TIF_NEED_RESCHED)) |
| + if (!preemptible_lazy()) |
| return; |
| -#endif |
| + |
| do { |
| preempt_disable_notrace(); |
| /* |