Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1301330 > unrolled thread
| Started by | Byungchul Park <byungchul.park@lge.com> |
|---|---|
| First post | 2016-01-05 10:00 +0100 |
| Last post | 2016-01-05 10:30 +0100 |
| Articles | 17 — 3 participants |
Back to article view | Back to linux.kernel
[STABLE] kernel oops which can be fixed by peterz's patches Byungchul Park <byungchul.park@lge.com> - 2016-01-05 10:00 +0100
[PATCH for v3.14.58 7/7] sched, dl: Convert switched_{from, to}_dl() / prio_changed_dl() to balance callbacks Byungchul Park <byungchul.park@lge.com> - 2016-01-05 10:20 +0100
Re: [STABLE] kernel oops which can be fixed by peterz's patches Peter Zijlstra <peterz@infradead.org> - 2016-01-05 10:20 +0100
Re: [STABLE] kernel oops which can be fixed by peterz's patches Byungchul Park <byungchul.park@lge.com> - 2016-01-12 09:50 +0100
Re: [STABLE] kernel oops which can be fixed by peterz's patches Willy Tarreau <w@1wt.eu> - 2016-01-12 11:30 +0100
[PATCH for v3.14.58 6/7] sched,dl: Remove return value from pull_dl_task() Byungchul Park <byungchul.park@lge.com> - 2016-01-05 10:20 +0100
[PATCH for v3.14.58 1/7] sched: Clean up idle task SMP logic Byungchul Park <byungchul.park@lge.com> - 2016-01-05 10:20 +0100
[PATCH for v3.14.58 4/7] sched,rt: Remove return value from pull_rt_task() Byungchul Park <byungchul.park@lge.com> - 2016-01-05 10:20 +0100
[PATCH for v3.14.58 2/7] sched: Replace post_schedule with a balance callback list Byungchul Park <byungchul.park@lge.com> - 2016-01-05 10:20 +0100
[PATCH for v3.14.58 3/7] sched: Allow balance callbacks for check_class_changed() Byungchul Park <byungchul.park@lge.com> - 2016-01-05 10:20 +0100
[PATCH for v3.14.58 5/7] sched, rt: Convert switched_{from, to}_rt() / prio_changed_rt() to balance callbacks Byungchul Park <byungchul.park@lge.com> - 2016-01-05 10:20 +0100
[PATCH for v3.18.25 1/6] sched: Replace post_schedule with a balance callback list Byungchul Park <byungchul.park@lge.com> - 2016-01-05 10:30 +0100
[PATCH for v3.18.25 3/6] sched,rt: Remove return value from pull_rt_task() Byungchul Park <byungchul.park@lge.com> - 2016-01-05 10:30 +0100
[PATCH for v3.18.25 4/6] sched, rt: Convert switched_{from, to}_rt() / prio_changed_rt() to balance callbacks Byungchul Park <byungchul.park@lge.com> - 2016-01-05 10:30 +0100
[PATCH for v3.18.25 6/6] sched, dl: Convert switched_{from, to}_dl() / prio_changed_dl() to balance callbacks Byungchul Park <byungchul.park@lge.com> - 2016-01-05 10:30 +0100
[PATCH for v3.18.25 5/6] sched,dl: Remove return value from pull_dl_task() Byungchul Park <byungchul.park@lge.com> - 2016-01-05 10:30 +0100
[PATCH for v3.18.25 2/6] sched: Allow balance callbacks for check_class_changed() Byungchul Park <byungchul.park@lge.com> - 2016-01-05 10:30 +0100
| From | Byungchul Park <byungchul.park@lge.com> |
|---|---|
| Date | 2016-01-05 10:00 +0100 |
| Subject | [STABLE] kernel oops which can be fixed by peterz's patches |
| Message-ID | <qNvDb-84L-11@gated-at.bofh.it> |
Upstream commits to be applied
==============================
e3fca9e: sched: Replace post_schedule with a balance callback list
4c9a4bc: sched: Allow balance callbacks for check_class_changed()
8046d68: sched,rt: Remove return value from pull_rt_task()
fd7a4be: sched, rt: Convert switched_{from, to}_rt() / prio_changed_rt() to balance callbacks
0ea60c2: sched,dl: Remove return value from pull_dl_task()
9916e21: sched, dl: Convert switched_{from, to}_dl() / prio_changed_dl() to balance callbacks
The reason why these should be applied
======================================
Our products developed using 3.16 kernel, faced a kernel oops which can
be fixed with above upstreamed patches. The oops is caused by "Unable
to handle kernel NULL pointer dereference at virtual address 000000xx"
in the call path,
__sched_setscheduler()
check_class_changed()
switched_to_fair()
check_preempt_curr()
check_preempt_wakeup()
find_matching_se()
is_same_group()
by "if (se->cfs_rq == pse->cfs_rq) // se, pse == NULL" condition.
How to apply it
===============
For stable 4.2.8+:
N/A (already applied)
For longterm 4.1.15:
Cherry-picking the upsteam commits works with a trivial conflict.
For longterm 3.18.25:
Refer to the backported patches in this thread.
For longterm 3.14.58:
Refer to the backported patches in this thread. And applying
additional "6c3b4d4: sched: Clean up idle task SMP logic" commit
makes backporting the upstream commits much simpler. So my
backporting patches include the patch.
For longterm 2.6.32.69 ~ 3.12.51: Need to be backported. (I didn't)
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [next] | [standalone]
| From | Byungchul Park <byungchul.park@lge.com> |
|---|---|
| Date | 2016-01-05 10:20 +0100 |
| Subject | [PATCH for v3.14.58 7/7] sched, dl: Convert switched_{from, to}_dl() / prio_changed_dl() to balance callbacks |
| Message-ID | <qNvWx-8rN-5@gated-at.bofh.it> |
| In reply to | #1301330 |
From: Peter Zijlstra <peterz@infradead.org>
Remove the direct {push,pull} balancing operations from
switched_{from,to}_dl() / prio_changed_dl() and use the balance
callback queue.
Again, err on the side of too many reschedules; since too few is a
hard bug while too many is just annoying.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: ktkhai@parallels.com
Cc: rostedt@goodmis.org
Cc: juri.lelli@gmail.com
Cc: pang.xunlei@linaro.org
Cc: oleg@redhat.com
Cc: wanpeng.li@linux.intel.com
Cc: umgwanakikbuti@gmail.com
Link: http://lkml.kernel.org/r/20150611124742.968262663@infradead.org
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Byungchul Park <byungchul.park@lge.com>
Conflicts:
kernel/sched/deadline.c
---
kernel/sched/deadline.c | 34 +++++++++++++++++++++-------------
1 file changed, 21 insertions(+), 13 deletions(-)
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
index ec1f21d..6ab59bb 100644
--- a/kernel/sched/deadline.c
+++ b/kernel/sched/deadline.c
@@ -210,16 +210,23 @@ static inline int has_pushable_dl_tasks(struct rq *rq)
static int push_dl_task(struct rq *rq);
-static DEFINE_PER_CPU(struct callback_head, dl_balance_head);
+static DEFINE_PER_CPU(struct callback_head, dl_push_head);
+static DEFINE_PER_CPU(struct callback_head, dl_pull_head);
static void push_dl_tasks(struct rq *);
+static void pull_dl_task(struct rq *);
static inline void queue_push_tasks(struct rq *rq)
{
if (!has_pushable_dl_tasks(rq))
return;
- queue_balance_callback(rq, &per_cpu(dl_balance_head, rq->cpu), push_dl_tasks);
+ queue_balance_callback(rq, &per_cpu(dl_push_head, rq->cpu), push_dl_tasks);
+}
+
+static inline void queue_pull_task(struct rq *rq)
+{
+ queue_balance_callback(rq, &per_cpu(dl_pull_head, rq->cpu), pull_dl_task);
}
#else
@@ -247,6 +254,10 @@ void dec_dl_migration(struct sched_dl_entity *dl_se, struct dl_rq *dl_rq)
static inline void queue_push_tasks(struct rq *rq)
{
}
+
+static inline void queue_pull_task(struct rq *rq)
+{
+}
#endif /* CONFIG_SMP */
static void enqueue_task_dl(struct rq *rq, struct task_struct *p, int flags);
@@ -1541,7 +1552,7 @@ static void switched_from_dl(struct rq *rq, struct task_struct *p)
* from an overloaded cpu, if any.
*/
if (!rq->dl.dl_nr_running)
- pull_dl_task(rq);
+ queue_pull_task(rq);
#endif
}
@@ -1551,8 +1562,6 @@ static void switched_from_dl(struct rq *rq, struct task_struct *p)
*/
static void switched_to_dl(struct rq *rq, struct task_struct *p)
{
- int check_resched = 1;
-
/*
* If p is throttled, don't consider the possibility
* of preempting rq->curr, the check will be done right
@@ -1563,12 +1572,12 @@ static void switched_to_dl(struct rq *rq, struct task_struct *p)
if (p->on_rq || rq->curr != p) {
#ifdef CONFIG_SMP
- if (rq->dl.overloaded && push_dl_task(rq) && rq != task_rq(p))
- /* Only reschedule if pushing failed */
- check_resched = 0;
-#endif /* CONFIG_SMP */
- if (check_resched && task_has_dl_policy(rq->curr))
+ if (rq->dl.overloaded)
+ queue_push_tasks(rq);
+#else
+ if (task_has_dl_policy(rq->curr))
check_preempt_curr_dl(rq, p, 0);
+#endif /* CONFIG_SMP */
}
}
@@ -1588,15 +1597,14 @@ static void prio_changed_dl(struct rq *rq, struct task_struct *p,
* or lowering its prio, so...
*/
if (!rq->dl.overloaded)
- pull_dl_task(rq);
+ queue_pull_task(rq);
/*
* If we now have a earlier deadline task than p,
* then reschedule, provided p is still on this
* runqueue.
*/
- if (dl_time_before(rq->dl.earliest_dl.curr, p->dl.deadline) &&
- rq->curr == p)
+ if (dl_time_before(rq->dl.earliest_dl.curr, p->dl.deadline))
resched_task(p);
#else
/*
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2016-01-05 10:20 +0100 |
| Message-ID | <qNvWx-8rN-1@gated-at.bofh.it> |
| In reply to | #1301330 |
On Tue, Jan 05, 2016 at 05:52:11PM +0900, Byungchul Park wrote:
>
> Upstream commits to be applied
> ==============================
>
> e3fca9e: sched: Replace post_schedule with a balance callback list
> 4c9a4bc: sched: Allow balance callbacks for check_class_changed()
> 8046d68: sched,rt: Remove return value from pull_rt_task()
> fd7a4be: sched, rt: Convert switched_{from, to}_rt() / prio_changed_rt() to balance callbacks
> 0ea60c2: sched,dl: Remove return value from pull_dl_task()
> 9916e21: sched, dl: Convert switched_{from, to}_dl() / prio_changed_dl() to balance callbacks
>
> The reason why these should be applied
> ======================================
>
> Our products developed using 3.16 kernel, faced a kernel oops which can
> be fixed with above upstreamed patches. The oops is caused by "Unable
> to handle kernel NULL pointer dereference at virtual address 000000xx"
> in the call path,
>
> __sched_setscheduler()
> check_class_changed()
> switched_to_fair()
> check_preempt_curr()
> check_preempt_wakeup()
> find_matching_se()
> is_same_group()
>
> by "if (se->cfs_rq == pse->cfs_rq) // se, pse == NULL" condition.
So the reason I didn't mark them for stable is that they were non
trivial, however they've been in for a while now and nothing broke, so I
suppose backporting them isn't a problem.
> How to apply it
> ===============
>
> For stable 4.2.8+:
> N/A (already applied)
>
> For longterm 4.1.15:
> Cherry-picking the upsteam commits works with a trivial conflict.
>
> For longterm 3.18.25:
> Refer to the backported patches in this thread.
>
> For longterm 3.14.58:
> Refer to the backported patches in this thread. And applying
> additional "6c3b4d4: sched: Clean up idle task SMP logic" commit
> makes backporting the upstream commits much simpler. So my
> backporting patches include the patch.
>
> For longterm 2.6.32.69 ~ 3.12.51: Need to be backported. (I didn't)
No objection as long as you've actually tested things etc..
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Byungchul Park <byungchul.park@lge.com> |
|---|---|
| Date | 2016-01-12 09:50 +0100 |
| Message-ID | <qQ2Ol-6OM-11@gated-at.bofh.it> |
| In reply to | #1301347 |
On Tue, Jan 05, 2016 at 10:14:44AM +0100, Peter Zijlstra wrote:
> On Tue, Jan 05, 2016 at 05:52:11PM +0900, Byungchul Park wrote:
> >
> > Upstream commits to be applied
> > ==============================
> >
> > e3fca9e: sched: Replace post_schedule with a balance callback list
> > 4c9a4bc: sched: Allow balance callbacks for check_class_changed()
> > 8046d68: sched,rt: Remove return value from pull_rt_task()
> > fd7a4be: sched, rt: Convert switched_{from, to}_rt() / prio_changed_rt() to balance callbacks
> > 0ea60c2: sched,dl: Remove return value from pull_dl_task()
> > 9916e21: sched, dl: Convert switched_{from, to}_dl() / prio_changed_dl() to balance callbacks
> >
> > The reason why these should be applied
> > ======================================
> >
> > Our products developed using 3.16 kernel, faced a kernel oops which can
> > be fixed with above upstreamed patches. The oops is caused by "Unable
> > to handle kernel NULL pointer dereference at virtual address 000000xx"
> > in the call path,
> >
> > __sched_setscheduler()
> > check_class_changed()
> > switched_to_fair()
> > check_preempt_curr()
> > check_preempt_wakeup()
> > find_matching_se()
> > is_same_group()
> >
> > by "if (se->cfs_rq == pse->cfs_rq) // se, pse == NULL" condition.
>
> So the reason I didn't mark them for stable is that they were non
> trivial, however they've been in for a while now and nothing broke, so I
> suppose backporting them isn't a problem.
Do you think the backporting can have some potential problems? I
checked if it worked well on my machine. Do you think it need more
tests to verify its stability?
>
> > How to apply it
> > ===============
> >
> > For stable 4.2.8+:
> > N/A (already applied)
> >
> > For longterm 4.1.15:
> > Cherry-picking the upsteam commits works with a trivial conflict.
> >
> > For longterm 3.18.25:
> > Refer to the backported patches in this thread.
> >
> > For longterm 3.14.58:
> > Refer to the backported patches in this thread. And applying
> > additional "6c3b4d4: sched: Clean up idle task SMP logic" commit
> > makes backporting the upstream commits much simpler. So my
> > backporting patches include the patch.
> >
> > For longterm 2.6.32.69 ~ 3.12.51: Need to be backported. (I didn't)
>
> No objection as long as you've actually tested things etc..
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Willy Tarreau <w@1wt.eu> |
|---|---|
| Date | 2016-01-12 11:30 +0100 |
| Message-ID | <qQ4n8-81P-5@gated-at.bofh.it> |
| In reply to | #1301347 |
Hi Peter,
On Tue, Jan 05, 2016 at 10:14:44AM +0100, Peter Zijlstra wrote:
> On Tue, Jan 05, 2016 at 05:52:11PM +0900, Byungchul Park wrote:
> >
> > Upstream commits to be applied
> > ==============================
> >
> > e3fca9e: sched: Replace post_schedule with a balance callback list
> > 4c9a4bc: sched: Allow balance callbacks for check_class_changed()
> > 8046d68: sched,rt: Remove return value from pull_rt_task()
> > fd7a4be: sched, rt: Convert switched_{from, to}_rt() / prio_changed_rt() to balance callbacks
> > 0ea60c2: sched,dl: Remove return value from pull_dl_task()
> > 9916e21: sched, dl: Convert switched_{from, to}_dl() / prio_changed_dl() to balance callbacks
> >
> > The reason why these should be applied
> > ======================================
> >
> > Our products developed using 3.16 kernel, faced a kernel oops which can
> > be fixed with above upstreamed patches. The oops is caused by "Unable
> > to handle kernel NULL pointer dereference at virtual address 000000xx"
> > in the call path,
> >
> > __sched_setscheduler()
> > check_class_changed()
> > switched_to_fair()
> > check_preempt_curr()
> > check_preempt_wakeup()
> > find_matching_se()
> > is_same_group()
> >
> > by "if (se->cfs_rq == pse->cfs_rq) // se, pse == NULL" condition.
>
> So the reason I didn't mark them for stable is that they were non
> trivial, however they've been in for a while now and nothing broke, so I
> suppose backporting them isn't a problem.
I didn't check the code, but for older kernels, can't we simply get rid
of the issue by adding an extra test on se/pse before dereferencing it,
even if that implies a suboptimal fix which is always better than an oops ?
I must confess I don't feel at ease with backporting so many sensitive
changes into 2.6.32!
Thanks,
Willy
[toc] | [prev] | [next] | [standalone]
| From | Byungchul Park <byungchul.park@lge.com> |
|---|---|
| Date | 2016-01-05 10:20 +0100 |
| Subject | [PATCH for v3.14.58 6/7] sched,dl: Remove return value from pull_dl_task() |
| Message-ID | <qNvWx-8rN-9@gated-at.bofh.it> |
| In reply to | #1301330 |
From: Peter Zijlstra <peterz@infradead.org>
In order to be able to use pull_dl_task() from a callback, we need to
do away with the return value.
Since the return value indicates if we should reschedule, do this
inside the function. Since not all callers currently do this, this can
increase the number of reschedules due rt balancing.
Too many reschedules is not a correctness issues, too few are.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: ktkhai@parallels.com
Cc: rostedt@goodmis.org
Cc: juri.lelli@gmail.com
Cc: pang.xunlei@linaro.org
Cc: oleg@redhat.com
Cc: wanpeng.li@linux.intel.com
Cc: umgwanakikbuti@gmail.com
Link: http://lkml.kernel.org/r/20150611124742.859398977@infradead.org
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Byungchul Park <byungchul.park@lge.com>
Conflicts:
kernel/sched/deadline.c
---
kernel/sched/deadline.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
index aaefe1b..ec1f21d 100644
--- a/kernel/sched/deadline.c
+++ b/kernel/sched/deadline.c
@@ -1351,15 +1351,16 @@ static void push_dl_tasks(struct rq *rq)
;
}
-static int pull_dl_task(struct rq *this_rq)
+static void pull_dl_task(struct rq *this_rq)
{
- int this_cpu = this_rq->cpu, ret = 0, cpu;
+ int this_cpu = this_rq->cpu, cpu;
struct task_struct *p;
+ bool resched = false;
struct rq *src_rq;
u64 dmin = LONG_MAX;
if (likely(!dl_overloaded(this_rq)))
- return 0;
+ return;
/*
* Match the barrier from dl_set_overloaded; this guarantees that if we
@@ -1414,7 +1415,7 @@ static int pull_dl_task(struct rq *this_rq)
src_rq->curr->dl.deadline))
goto skip;
- ret = 1;
+ resched = true;
deactivate_task(src_rq, p, 0);
set_task_cpu(p, this_cpu);
@@ -1427,7 +1428,8 @@ skip:
double_unlock_balance(this_rq, src_rq);
}
- return ret;
+ if (resched)
+ resched_task(this_rq->curr);
}
static void pre_schedule_dl(struct rq *rq, struct task_struct *prev)
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Byungchul Park <byungchul.park@lge.com> |
|---|---|
| Date | 2016-01-05 10:20 +0100 |
| Subject | [PATCH for v3.14.58 1/7] sched: Clean up idle task SMP logic |
| Message-ID | <qNvWx-8rN-7@gated-at.bofh.it> |
| In reply to | #1301330 |
From: Peter Zijlstra <peterz@infradead.org>
The idle post_schedule flag is just a vile waste of time, furthermore
it appears unneeded, move the idle_enter_fair() call into
pick_next_task_idle().
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Vincent Guittot <vincent.guittot@linaro.org>
Cc: alex.shi@linaro.org
Cc: mingo@kernel.org
Cc: Steven Rostedt <rostedt@goodmis.org>
Link: http://lkml.kernel.org/n/tip-aljykihtxJt3mkokxi0qZurb@git.kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
kernel/sched/idle_task.c | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/kernel/sched/idle_task.c b/kernel/sched/idle_task.c
index 516c3d9..d08678d 100644
--- a/kernel/sched/idle_task.c
+++ b/kernel/sched/idle_task.c
@@ -19,11 +19,6 @@ static void pre_schedule_idle(struct rq *rq, struct task_struct *prev)
idle_exit_fair(rq);
rq_last_tick_reset(rq);
}
-
-static void post_schedule_idle(struct rq *rq)
-{
- idle_enter_fair(rq);
-}
#endif /* CONFIG_SMP */
/*
* Idle tasks are unconditionally rescheduled:
@@ -37,8 +32,7 @@ static struct task_struct *pick_next_task_idle(struct rq *rq)
{
schedstat_inc(rq, sched_goidle);
#ifdef CONFIG_SMP
- /* Trigger the post schedule to do an idle_enter for CFS */
- rq->post_schedule = 1;
+ idle_enter_fair(rq);
#endif
return rq->idle;
}
@@ -102,7 +96,6 @@ const struct sched_class idle_sched_class = {
#ifdef CONFIG_SMP
.select_task_rq = select_task_rq_idle,
.pre_schedule = pre_schedule_idle,
- .post_schedule = post_schedule_idle,
#endif
.set_curr_task = set_curr_task_idle,
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Byungchul Park <byungchul.park@lge.com> |
|---|---|
| Date | 2016-01-05 10:20 +0100 |
| Subject | [PATCH for v3.14.58 4/7] sched,rt: Remove return value from pull_rt_task() |
| Message-ID | <qNvWy-8rN-15@gated-at.bofh.it> |
| In reply to | #1301349 |
From: Peter Zijlstra <peterz@infradead.org>
In order to be able to use pull_rt_task() from a callback, we need to
do away with the return value.
Since the return value indicates if we should reschedule, do this
inside the function. Since not all callers currently do this, this can
increase the number of reschedules due rt balancing.
Too many reschedules is not a correctness issues, too few are.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: ktkhai@parallels.com
Cc: rostedt@goodmis.org
Cc: juri.lelli@gmail.com
Cc: pang.xunlei@linaro.org
Cc: oleg@redhat.com
Cc: wanpeng.li@linux.intel.com
Cc: umgwanakikbuti@gmail.com
Link: http://lkml.kernel.org/r/20150611124742.679002000@infradead.org
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Byungchul Park <byungchul.park@lge.com>
Conflicts:
kernel/sched/rt.c
---
kernel/sched/rt.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 2b980d0..d235fd7 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -1652,14 +1652,15 @@ static void push_rt_tasks(struct rq *rq)
;
}
-static int pull_rt_task(struct rq *this_rq)
+static void pull_rt_task(struct rq *this_rq)
{
- int this_cpu = this_rq->cpu, ret = 0, cpu;
+ int this_cpu = this_rq->cpu, cpu;
+ bool resched = false;
struct task_struct *p;
struct rq *src_rq;
if (likely(!rt_overloaded(this_rq)))
- return 0;
+ return;
/*
* Match the barrier from rt_set_overloaded; this guarantees that if we
@@ -1716,7 +1717,7 @@ static int pull_rt_task(struct rq *this_rq)
if (p->prio < src_rq->curr->prio)
goto skip;
- ret = 1;
+ resched = true;
deactivate_task(src_rq, p, 0);
set_task_cpu(p, this_cpu);
@@ -1732,7 +1733,8 @@ skip:
double_unlock_balance(this_rq, src_rq);
}
- return ret;
+ if (resched)
+ resched_task(this_rq->curr);
}
static void pre_schedule_rt(struct rq *rq, struct task_struct *prev)
@@ -1835,8 +1837,7 @@ static void switched_from_rt(struct rq *rq, struct task_struct *p)
if (!p->on_rq || rq->rt.rt_nr_running)
return;
- if (pull_rt_task(rq))
- resched_task(rq->curr);
+ pull_rt_task(rq);
}
void init_sched_rt_class(void)
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Byungchul Park <byungchul.park@lge.com> |
|---|---|
| Date | 2016-01-05 10:20 +0100 |
| Subject | [PATCH for v3.14.58 2/7] sched: Replace post_schedule with a balance callback list |
| Message-ID | <qNvWy-8rN-13@gated-at.bofh.it> |
| In reply to | #1301349 |
From: Peter Zijlstra <peterz@infradead.org>
Generalize the post_schedule() stuff into a balance callback list.
This allows us to more easily use it outside of schedule() and cross
sched_class.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: ktkhai@parallels.com
Cc: rostedt@goodmis.org
Cc: juri.lelli@gmail.com
Cc: pang.xunlei@linaro.org
Cc: oleg@redhat.com
Cc: wanpeng.li@linux.intel.com
Cc: umgwanakikbuti@gmail.com
Link: http://lkml.kernel.org/r/20150611124742.424032725@infradead.org
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Byungchul Park <byungchul.park@lge.com>
Conflicts:
kernel/sched/core.c
kernel/sched/deadline.c
kernel/sched/rt.c
kernel/sched/sched.h
---
kernel/sched/core.c | 36 ++++++++++++++++++++++++------------
kernel/sched/deadline.c | 23 ++++++++++++++++-------
kernel/sched/rt.c | 27 ++++++++++++++++-----------
kernel/sched/sched.h | 19 +++++++++++++++++--
4 files changed, 73 insertions(+), 32 deletions(-)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index bbe9577..cc1be56 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -2179,18 +2179,30 @@ static inline void pre_schedule(struct rq *rq, struct task_struct *prev)
}
/* rq->lock is NOT held, but preemption is disabled */
-static inline void post_schedule(struct rq *rq)
+static void __balance_callback(struct rq *rq)
{
- if (rq->post_schedule) {
- unsigned long flags;
+ struct callback_head *head, *next;
+ void (*func)(struct rq *rq);
+ unsigned long flags;
- raw_spin_lock_irqsave(&rq->lock, flags);
- if (rq->curr->sched_class->post_schedule)
- rq->curr->sched_class->post_schedule(rq);
- raw_spin_unlock_irqrestore(&rq->lock, flags);
+ raw_spin_lock_irqsave(&rq->lock, flags);
+ head = rq->balance_callback;
+ rq->balance_callback = NULL;
+ while (head) {
+ func = (void (*)(struct rq *))head->func;
+ next = head->next;
+ head->next = NULL;
+ head = next;
- rq->post_schedule = 0;
+ func(rq);
}
+ raw_spin_unlock_irqrestore(&rq->lock, flags);
+}
+
+static inline void balance_callback(struct rq *rq)
+{
+ if (unlikely(rq->balance_callback))
+ __balance_callback(rq);
}
#else
@@ -2199,7 +2211,7 @@ static inline void pre_schedule(struct rq *rq, struct task_struct *p)
{
}
-static inline void post_schedule(struct rq *rq)
+static inline void balance_callback(struct rq *rq)
{
}
@@ -2220,7 +2232,7 @@ asmlinkage void schedule_tail(struct task_struct *prev)
* FIXME: do we need to worry about rq being invalidated by the
* task_switch?
*/
- post_schedule(rq);
+ balance_callback(rq);
#ifdef __ARCH_WANT_UNLOCKED_CTXSW
/* In this case, finish_task_switch does not reenable preemption */
@@ -2732,7 +2744,7 @@ need_resched:
} else
raw_spin_unlock_irq(&rq->lock);
- post_schedule(rq);
+ balance_callback(rq);
sched_preempt_enable_no_resched();
if (need_resched())
@@ -6902,7 +6914,7 @@ void __init sched_init(void)
rq->sd = NULL;
rq->rd = NULL;
rq->cpu_power = SCHED_POWER_SCALE;
- rq->post_schedule = 0;
+ rq->balance_callback = NULL;
rq->active_balance = 0;
rq->next_balance = jiffies;
rq->push_cpu = 0;
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
index 8d3c5dd..aaefe1b 100644
--- a/kernel/sched/deadline.c
+++ b/kernel/sched/deadline.c
@@ -210,6 +210,18 @@ static inline int has_pushable_dl_tasks(struct rq *rq)
static int push_dl_task(struct rq *rq);
+static DEFINE_PER_CPU(struct callback_head, dl_balance_head);
+
+static void push_dl_tasks(struct rq *);
+
+static inline void queue_push_tasks(struct rq *rq)
+{
+ if (!has_pushable_dl_tasks(rq))
+ return;
+
+ queue_balance_callback(rq, &per_cpu(dl_balance_head, rq->cpu), push_dl_tasks);
+}
+
#else
static inline
@@ -232,6 +244,9 @@ void dec_dl_migration(struct sched_dl_entity *dl_se, struct dl_rq *dl_rq)
{
}
+static inline void queue_push_tasks(struct rq *rq)
+{
+}
#endif /* CONFIG_SMP */
static void enqueue_task_dl(struct rq *rq, struct task_struct *p, int flags);
@@ -1005,7 +1020,7 @@ struct task_struct *pick_next_task_dl(struct rq *rq)
#endif
#ifdef CONFIG_SMP
- rq->post_schedule = has_pushable_dl_tasks(rq);
+ queue_push_tasks(rq);
#endif /* CONFIG_SMP */
return p;
@@ -1422,11 +1437,6 @@ static void pre_schedule_dl(struct rq *rq, struct task_struct *prev)
pull_dl_task(rq);
}
-static void post_schedule_dl(struct rq *rq)
-{
- push_dl_tasks(rq);
-}
-
/*
* Since the task is not running and a reschedule is not going to happen
* anytime soon on its runqueue, we try pushing it away now.
@@ -1615,7 +1625,6 @@ const struct sched_class dl_sched_class = {
.rq_online = rq_online_dl,
.rq_offline = rq_offline_dl,
.pre_schedule = pre_schedule_dl,
- .post_schedule = post_schedule_dl,
.task_woken = task_woken_dl,
#endif
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 27b8e83..2b980d0 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -315,6 +315,18 @@ static inline int has_pushable_tasks(struct rq *rq)
return !plist_head_empty(&rq->rt.pushable_tasks);
}
+static DEFINE_PER_CPU(struct callback_head, rt_balance_head);
+
+static void push_rt_tasks(struct rq *);
+
+static inline void queue_push_tasks(struct rq *rq)
+{
+ if (!has_pushable_tasks(rq))
+ return;
+
+ queue_balance_callback(rq, &per_cpu(rt_balance_head, rq->cpu), push_rt_tasks);
+}
+
static void enqueue_pushable_task(struct rq *rq, struct task_struct *p)
{
plist_del(&p->pushable_tasks, &rq->rt.pushable_tasks);
@@ -359,6 +371,9 @@ void dec_rt_migration(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq)
{
}
+static inline void queue_push_tasks(struct rq *rq)
+{
+}
#endif /* CONFIG_SMP */
static inline int on_rt_rq(struct sched_rt_entity *rt_se)
@@ -1349,11 +1364,7 @@ static struct task_struct *pick_next_task_rt(struct rq *rq)
dequeue_pushable_task(rq, p);
#ifdef CONFIG_SMP
- /*
- * We detect this state here so that we can avoid taking the RQ
- * lock again later if there is no need to push
- */
- rq->post_schedule = has_pushable_tasks(rq);
+ queue_push_tasks(rq);
#endif
return p;
@@ -1731,11 +1742,6 @@ static void pre_schedule_rt(struct rq *rq, struct task_struct *prev)
pull_rt_task(rq);
}
-static void post_schedule_rt(struct rq *rq)
-{
- push_rt_tasks(rq);
-}
-
/*
* If we are not running and we are not going to reschedule soon, we should
* try to push tasks away now
@@ -2008,7 +2014,6 @@ const struct sched_class rt_sched_class = {
.rq_online = rq_online_rt,
.rq_offline = rq_offline_rt,
.pre_schedule = pre_schedule_rt,
- .post_schedule = post_schedule_rt,
.task_woken = task_woken_rt,
.switched_from = switched_from_rt,
#endif
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 835b6ef..675e147 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -587,9 +587,10 @@ struct rq {
unsigned long cpu_power;
+ struct callback_head *balance_callback;
+
unsigned char idle_balance;
/* For active balancing */
- int post_schedule;
int active_balance;
int push_cpu;
struct cpu_stop_work active_balance_work;
@@ -690,6 +691,21 @@ extern int migrate_swap(struct task_struct *, struct task_struct *);
#ifdef CONFIG_SMP
+static inline void
+queue_balance_callback(struct rq *rq,
+ struct callback_head *head,
+ void (*func)(struct rq *rq))
+{
+ lockdep_assert_held(&rq->lock);
+
+ if (unlikely(head->next))
+ return;
+
+ head->func = (void (*)(struct callback_head *))func;
+ head->next = rq->balance_callback;
+ rq->balance_callback = head;
+}
+
#define rcu_dereference_check_sched_domain(p) \
rcu_dereference_check((p), \
lockdep_is_held(&sched_domains_mutex))
@@ -1131,7 +1147,6 @@ struct sched_class {
void (*migrate_task_rq)(struct task_struct *p, int next_cpu);
void (*pre_schedule) (struct rq *this_rq, struct task_struct *task);
- void (*post_schedule) (struct rq *this_rq);
void (*task_waking) (struct task_struct *task);
void (*task_woken) (struct rq *this_rq, struct task_struct *task);
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Byungchul Park <byungchul.park@lge.com> |
|---|---|
| Date | 2016-01-05 10:20 +0100 |
| Subject | [PATCH for v3.14.58 3/7] sched: Allow balance callbacks for check_class_changed() |
| Message-ID | <qNvWy-8rN-17@gated-at.bofh.it> |
| In reply to | #1301349 |
From: Peter Zijlstra <peterz@infradead.org>
In order to remove dropping rq->lock from the
switched_{to,from}()/prio_changed() sched_class methods, run the
balance callbacks after it.
We need to remove dropping rq->lock because its buggy,
suppose using sched_setattr()/sched_setscheduler() to change a running
task from FIFO to OTHER.
By the time we get to switched_from_rt() the task is already enqueued
on the cfs runqueues. If switched_from_rt() does pull_rt_task() and
drops rq->lock, load-balancing can come in and move our task @p to
another rq.
The subsequent switched_to_fair() still assumes @p is on @rq and bad
things will happen.
By using balance callbacks we delay the load-balancing operations
{rt,dl}x{push,pull} until we've done all the important work and the
task is fully set up.
Furthermore, the balance callbacks do not know about @p, therefore
they cannot get confused like this.
Reported-by: Mike Galbraith <umgwanakikbuti@gmail.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: ktkhai@parallels.com
Cc: rostedt@goodmis.org
Cc: juri.lelli@gmail.com
Cc: pang.xunlei@linaro.org
Cc: oleg@redhat.com
Cc: wanpeng.li@linux.intel.com
Link: http://lkml.kernel.org/r/20150611124742.615343911@infradead.org
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Byungchul Park <byungchul.park@lge.com>
Conflicts:
kernel/sched/core.c
---
kernel/sched/core.c | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index cc1be56..459cc86 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -937,6 +937,13 @@ inline int task_curr(const struct task_struct *p)
return cpu_curr(task_cpu(p)) == p;
}
+/*
+ * switched_from, switched_to and prio_changed must _NOT_ drop rq->lock,
+ * use the balance_callback list if you want balancing.
+ *
+ * this means any call to check_class_changed() must be followed by a call to
+ * balance_callback().
+ */
static inline void check_class_changed(struct rq *rq, struct task_struct *p,
const struct sched_class *prev_class,
int oldprio)
@@ -1423,8 +1430,12 @@ ttwu_do_wakeup(struct rq *rq, struct task_struct *p, int wake_flags)
p->state = TASK_RUNNING;
#ifdef CONFIG_SMP
- if (p->sched_class->task_woken)
+ if (p->sched_class->task_woken) {
+ /*
+ * XXX can drop rq->lock; most likely ok.
+ */
p->sched_class->task_woken(rq, p);
+ }
if (rq->idle_stamp) {
u64 delta = rq_clock(rq) - rq->idle_stamp;
@@ -3006,7 +3017,11 @@ void rt_mutex_setprio(struct task_struct *p, int prio)
check_class_changed(rq, p, prev_class, oldprio);
out_unlock:
+ preempt_disable(); /* avoid rq from going away on us */
__task_rq_unlock(rq);
+
+ balance_callback(rq);
+ preempt_enable();
}
#endif
@@ -3512,10 +3527,17 @@ change:
enqueue_task(rq, p, 0);
check_class_changed(rq, p, prev_class, oldprio);
+ preempt_disable(); /* avoid rq from going away on us */
task_rq_unlock(rq, p, &flags);
rt_mutex_adjust_pi(p);
+ /*
+ * Run balance callbacks after we've adjusted the PI chain.
+ */
+ balance_callback(rq);
+ preempt_enable();
+
return 0;
}
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Byungchul Park <byungchul.park@lge.com> |
|---|---|
| Date | 2016-01-05 10:20 +0100 |
| Subject | [PATCH for v3.14.58 5/7] sched, rt: Convert switched_{from, to}_rt() / prio_changed_rt() to balance callbacks |
| Message-ID | <qNvWy-8rN-21@gated-at.bofh.it> |
| In reply to | #1301349 |
From: Peter Zijlstra <peterz@infradead.org>
Remove the direct {push,pull} balancing operations from
switched_{from,to}_rt() / prio_changed_rt() and use the balance
callback queue.
Again, err on the side of too many reschedules; since too few is a
hard bug while too many is just annoying.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: ktkhai@parallels.com
Cc: rostedt@goodmis.org
Cc: juri.lelli@gmail.com
Cc: pang.xunlei@linaro.org
Cc: oleg@redhat.com
Cc: wanpeng.li@linux.intel.com
Cc: umgwanakikbuti@gmail.com
Link: http://lkml.kernel.org/r/20150611124742.766832367@infradead.org
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Byungchul Park <byungchul.park@lge.com>
Conflicts:
kernel/sched/rt.c
---
kernel/sched/rt.c | 35 +++++++++++++++++++----------------
1 file changed, 19 insertions(+), 16 deletions(-)
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index d235fd7..0fb72ae 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -315,16 +315,23 @@ static inline int has_pushable_tasks(struct rq *rq)
return !plist_head_empty(&rq->rt.pushable_tasks);
}
-static DEFINE_PER_CPU(struct callback_head, rt_balance_head);
+static DEFINE_PER_CPU(struct callback_head, rt_push_head);
+static DEFINE_PER_CPU(struct callback_head, rt_pull_head);
static void push_rt_tasks(struct rq *);
+static void pull_rt_task(struct rq *);
static inline void queue_push_tasks(struct rq *rq)
{
if (!has_pushable_tasks(rq))
return;
- queue_balance_callback(rq, &per_cpu(rt_balance_head, rq->cpu), push_rt_tasks);
+ queue_balance_callback(rq, &per_cpu(rt_push_head, rq->cpu), push_rt_tasks);
+}
+
+static inline void queue_pull_task(struct rq *rq)
+{
+ queue_balance_callback(rq, &per_cpu(rt_pull_head, rq->cpu), pull_rt_task);
}
static void enqueue_pushable_task(struct rq *rq, struct task_struct *p)
@@ -1837,7 +1844,7 @@ static void switched_from_rt(struct rq *rq, struct task_struct *p)
if (!p->on_rq || rq->rt.rt_nr_running)
return;
- pull_rt_task(rq);
+ queue_pull_task(rq);
}
void init_sched_rt_class(void)
@@ -1858,8 +1865,6 @@ void init_sched_rt_class(void)
*/
static void switched_to_rt(struct rq *rq, struct task_struct *p)
{
- int check_resched = 1;
-
/*
* If we are already running, then there's nothing
* that needs to be done. But if we are not running
@@ -1869,13 +1874,12 @@ static void switched_to_rt(struct rq *rq, struct task_struct *p)
*/
if (p->on_rq && rq->curr != p) {
#ifdef CONFIG_SMP
- if (rq->rt.overloaded && push_rt_task(rq) &&
- /* Don't resched if we changed runqueues */
- rq != task_rq(p))
- check_resched = 0;
-#endif /* CONFIG_SMP */
- if (check_resched && p->prio < rq->curr->prio)
+ if (rq->rt.overloaded)
+ queue_push_tasks(rq);
+#else
+ if (p->prio < rq->curr->prio)
resched_task(rq->curr);
+#endif /* CONFIG_SMP */
}
}
@@ -1896,14 +1900,13 @@ prio_changed_rt(struct rq *rq, struct task_struct *p, int oldprio)
* may need to pull tasks to this runqueue.
*/
if (oldprio < p->prio)
- pull_rt_task(rq);
+ queue_pull_task(rq);
+
/*
* If there's a higher priority task waiting to run
- * then reschedule. Note, the above pull_rt_task
- * can release the rq lock and p could migrate.
- * Only reschedule if p is still on the same runqueue.
+ * then reschedule.
*/
- if (p->prio > rq->rt.highest_prio.curr && rq->curr == p)
+ if (p->prio > rq->rt.highest_prio.curr)
resched_task(p);
#else
/* For UP simply resched on drop of prio */
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Byungchul Park <byungchul.park@lge.com> |
|---|---|
| Date | 2016-01-05 10:30 +0100 |
| Subject | [PATCH for v3.18.25 1/6] sched: Replace post_schedule with a balance callback list |
| Message-ID | <qNw6d-5k-1@gated-at.bofh.it> |
| In reply to | #1301330 |
From: Peter Zijlstra <peterz@infradead.org>
Generalize the post_schedule() stuff into a balance callback list.
This allows us to more easily use it outside of schedule() and cross
sched_class.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: ktkhai@parallels.com
Cc: rostedt@goodmis.org
Cc: juri.lelli@gmail.com
Cc: pang.xunlei@linaro.org
Cc: oleg@redhat.com
Cc: wanpeng.li@linux.intel.com
Cc: umgwanakikbuti@gmail.com
Link: http://lkml.kernel.org/r/20150611124742.424032725@infradead.org
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Byungchul Park <byungchul.park@lge.com>
Conflicts:
kernel/sched/core.c
---
kernel/sched/core.c | 36 ++++++++++++++++++++++++------------
kernel/sched/deadline.c | 21 +++++++++++----------
kernel/sched/rt.c | 25 +++++++++++--------------
kernel/sched/sched.h | 19 +++++++++++++++++--
4 files changed, 63 insertions(+), 38 deletions(-)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index a38f987..3dff0ef 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -2240,23 +2240,35 @@ static void finish_task_switch(struct rq *rq, struct task_struct *prev)
#ifdef CONFIG_SMP
/* rq->lock is NOT held, but preemption is disabled */
-static inline void post_schedule(struct rq *rq)
+static void __balance_callback(struct rq *rq)
{
- if (rq->post_schedule) {
- unsigned long flags;
+ struct callback_head *head, *next;
+ void (*func)(struct rq *rq);
+ unsigned long flags;
- raw_spin_lock_irqsave(&rq->lock, flags);
- if (rq->curr->sched_class->post_schedule)
- rq->curr->sched_class->post_schedule(rq);
- raw_spin_unlock_irqrestore(&rq->lock, flags);
+ raw_spin_lock_irqsave(&rq->lock, flags);
+ head = rq->balance_callback;
+ rq->balance_callback = NULL;
+ while (head) {
+ func = (void (*)(struct rq *))head->func;
+ next = head->next;
+ head->next = NULL;
+ head = next;
- rq->post_schedule = 0;
+ func(rq);
}
+ raw_spin_unlock_irqrestore(&rq->lock, flags);
+}
+
+static inline void balance_callback(struct rq *rq)
+{
+ if (unlikely(rq->balance_callback))
+ __balance_callback(rq);
}
#else
-static inline void post_schedule(struct rq *rq)
+static inline void balance_callback(struct rq *rq)
{
}
@@ -2277,7 +2289,7 @@ asmlinkage __visible void schedule_tail(struct task_struct *prev)
* FIXME: do we need to worry about rq being invalidated by the
* task_switch?
*/
- post_schedule(rq);
+ balance_callback(rq);
#ifdef __ARCH_WANT_UNLOCKED_CTXSW
/* In this case, finish_task_switch does not reenable preemption */
@@ -2804,7 +2816,7 @@ need_resched:
} else
raw_spin_unlock_irq(&rq->lock);
- post_schedule(rq);
+ balance_callback(rq);
sched_preempt_enable_no_resched();
if (need_resched())
@@ -6973,7 +6985,7 @@ void __init sched_init(void)
rq->sd = NULL;
rq->rd = NULL;
rq->cpu_capacity = SCHED_CAPACITY_SCALE;
- rq->post_schedule = 0;
+ rq->balance_callback = NULL;
rq->active_balance = 0;
rq->next_balance = jiffies;
rq->push_cpu = 0;
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
index fc4f98b1..3bdf558 100644
--- a/kernel/sched/deadline.c
+++ b/kernel/sched/deadline.c
@@ -213,9 +213,16 @@ static inline bool need_pull_dl_task(struct rq *rq, struct task_struct *prev)
return dl_task(prev);
}
-static inline void set_post_schedule(struct rq *rq)
+static DEFINE_PER_CPU(struct callback_head, dl_balance_head);
+
+static void push_dl_tasks(struct rq *);
+
+static inline void queue_push_tasks(struct rq *rq)
{
- rq->post_schedule = has_pushable_dl_tasks(rq);
+ if (!has_pushable_dl_tasks(rq))
+ return;
+
+ queue_balance_callback(rq, &per_cpu(dl_balance_head, rq->cpu), push_dl_tasks);
}
#else
@@ -250,7 +257,7 @@ static inline int pull_dl_task(struct rq *rq)
return 0;
}
-static inline void set_post_schedule(struct rq *rq)
+static inline void queue_push_tasks(struct rq *rq)
{
}
#endif /* CONFIG_SMP */
@@ -1060,7 +1067,7 @@ struct task_struct *pick_next_task_dl(struct rq *rq, struct task_struct *prev)
start_hrtick_dl(rq, p);
#endif
- set_post_schedule(rq);
+ queue_push_tasks(rq);
return p;
}
@@ -1469,11 +1476,6 @@ skip:
return ret;
}
-static void post_schedule_dl(struct rq *rq)
-{
- push_dl_tasks(rq);
-}
-
/*
* Since the task is not running and a reschedule is not going to happen
* anytime soon on its runqueue, we try pushing it away now.
@@ -1661,7 +1663,6 @@ const struct sched_class dl_sched_class = {
.set_cpus_allowed = set_cpus_allowed_dl,
.rq_online = rq_online_dl,
.rq_offline = rq_offline_dl,
- .post_schedule = post_schedule_dl,
.task_woken = task_woken_dl,
#endif
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index a490831..5a91237 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -338,13 +338,16 @@ static inline int has_pushable_tasks(struct rq *rq)
return !plist_head_empty(&rq->rt.pushable_tasks);
}
-static inline void set_post_schedule(struct rq *rq)
+static DEFINE_PER_CPU(struct callback_head, rt_balance_head);
+
+static void push_rt_tasks(struct rq *);
+
+static inline void queue_push_tasks(struct rq *rq)
{
- /*
- * We detect this state here so that we can avoid taking the RQ
- * lock again later if there is no need to push
- */
- rq->post_schedule = has_pushable_tasks(rq);
+ if (!has_pushable_tasks(rq))
+ return;
+
+ queue_balance_callback(rq, &per_cpu(rt_balance_head, rq->cpu), push_rt_tasks);
}
static void enqueue_pushable_task(struct rq *rq, struct task_struct *p)
@@ -401,7 +404,7 @@ static inline int pull_rt_task(struct rq *this_rq)
return 0;
}
-static inline void set_post_schedule(struct rq *rq)
+static inline void queue_push_tasks(struct rq *rq)
{
}
#endif /* CONFIG_SMP */
@@ -1467,7 +1470,7 @@ pick_next_task_rt(struct rq *rq, struct task_struct *prev)
if (p)
dequeue_pushable_task(rq, p);
- set_post_schedule(rq);
+ queue_push_tasks(rq);
return p;
}
@@ -1837,11 +1840,6 @@ skip:
return ret;
}
-static void post_schedule_rt(struct rq *rq)
-{
- push_rt_tasks(rq);
-}
-
/*
* If we are not running and we are not going to reschedule soon, we should
* try to push tasks away now
@@ -2113,7 +2111,6 @@ const struct sched_class rt_sched_class = {
.set_cpus_allowed = set_cpus_allowed_rt,
.rq_online = rq_online_rt,
.rq_offline = rq_offline_rt,
- .post_schedule = post_schedule_rt,
.task_woken = task_woken_rt,
.switched_from = switched_from_rt,
#endif
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 31cc02e..045e008 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -569,9 +569,10 @@ struct rq {
unsigned long cpu_capacity;
+ struct callback_head *balance_callback;
+
unsigned char idle_balance;
/* For active balancing */
- int post_schedule;
int active_balance;
int push_cpu;
struct cpu_stop_work active_balance_work;
@@ -670,6 +671,21 @@ extern int migrate_swap(struct task_struct *, struct task_struct *);
#ifdef CONFIG_SMP
+static inline void
+queue_balance_callback(struct rq *rq,
+ struct callback_head *head,
+ void (*func)(struct rq *rq))
+{
+ lockdep_assert_held(&rq->lock);
+
+ if (unlikely(head->next))
+ return;
+
+ head->func = (void (*)(struct callback_head *))func;
+ head->next = rq->balance_callback;
+ rq->balance_callback = head;
+}
+
extern void sched_ttwu_pending(void);
#define rcu_dereference_check_sched_domain(p) \
@@ -1126,7 +1142,6 @@ struct sched_class {
int (*select_task_rq)(struct task_struct *p, int task_cpu, int sd_flag, int flags);
void (*migrate_task_rq)(struct task_struct *p, int next_cpu);
- void (*post_schedule) (struct rq *this_rq);
void (*task_waking) (struct task_struct *task);
void (*task_woken) (struct rq *this_rq, struct task_struct *task);
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Byungchul Park <byungchul.park@lge.com> |
|---|---|
| Date | 2016-01-05 10:30 +0100 |
| Subject | [PATCH for v3.18.25 3/6] sched,rt: Remove return value from pull_rt_task() |
| Message-ID | <qNw6e-5k-13@gated-at.bofh.it> |
| In reply to | #1301357 |
From: Peter Zijlstra <peterz@infradead.org>
In order to be able to use pull_rt_task() from a callback, we need to
do away with the return value.
Since the return value indicates if we should reschedule, do this
inside the function. Since not all callers currently do this, this can
increase the number of reschedules due rt balancing.
Too many reschedules is not a correctness issues, too few are.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: ktkhai@parallels.com
Cc: rostedt@goodmis.org
Cc: juri.lelli@gmail.com
Cc: pang.xunlei@linaro.org
Cc: oleg@redhat.com
Cc: wanpeng.li@linux.intel.com
Cc: umgwanakikbuti@gmail.com
Link: http://lkml.kernel.org/r/20150611124742.679002000@infradead.org
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Byungchul Park <byungchul.park@lge.com>
Conflicts:
kernel/sched/rt.c
---
kernel/sched/rt.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 5a91237..ce807aa 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -244,7 +244,7 @@ int alloc_rt_sched_group(struct task_group *tg, struct task_group *parent)
#ifdef CONFIG_SMP
-static int pull_rt_task(struct rq *this_rq);
+static void pull_rt_task(struct rq *this_rq);
static inline bool need_pull_rt_task(struct rq *rq, struct task_struct *prev)
{
@@ -399,9 +399,8 @@ static inline bool need_pull_rt_task(struct rq *rq, struct task_struct *prev)
return false;
}
-static inline int pull_rt_task(struct rq *this_rq)
+static inline void pull_rt_task(struct rq *this_rq)
{
- return 0;
}
static inline void queue_push_tasks(struct rq *rq)
@@ -1757,14 +1756,15 @@ static void push_rt_tasks(struct rq *rq)
;
}
-static int pull_rt_task(struct rq *this_rq)
+static void pull_rt_task(struct rq *this_rq)
{
- int this_cpu = this_rq->cpu, ret = 0, cpu;
+ int this_cpu = this_rq->cpu, cpu;
+ bool resched = false;
struct task_struct *p;
struct rq *src_rq;
if (likely(!rt_overloaded(this_rq)))
- return 0;
+ return;
/*
* Match the barrier from rt_set_overloaded; this guarantees that if we
@@ -1821,7 +1821,7 @@ static int pull_rt_task(struct rq *this_rq)
if (p->prio < src_rq->curr->prio)
goto skip;
- ret = 1;
+ resched = true;
deactivate_task(src_rq, p, 0);
set_task_cpu(p, this_cpu);
@@ -1837,7 +1837,8 @@ skip:
double_unlock_balance(this_rq, src_rq);
}
- return ret;
+ if (resched)
+ resched_curr(this_rq);
}
/*
@@ -1933,8 +1934,7 @@ static void switched_from_rt(struct rq *rq, struct task_struct *p)
if (!p->on_rq || rq->rt.rt_nr_running)
return;
- if (pull_rt_task(rq))
- resched_curr(rq);
+ pull_rt_task(rq);
}
void __init init_sched_rt_class(void)
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Byungchul Park <byungchul.park@lge.com> |
|---|---|
| Date | 2016-01-05 10:30 +0100 |
| Subject | [PATCH for v3.18.25 4/6] sched, rt: Convert switched_{from, to}_rt() / prio_changed_rt() to balance callbacks |
| Message-ID | <qNw6e-5k-11@gated-at.bofh.it> |
| In reply to | #1301357 |
From: Peter Zijlstra <peterz@infradead.org>
Remove the direct {push,pull} balancing operations from
switched_{from,to}_rt() / prio_changed_rt() and use the balance
callback queue.
Again, err on the side of too many reschedules; since too few is a
hard bug while too many is just annoying.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: ktkhai@parallels.com
Cc: rostedt@goodmis.org
Cc: juri.lelli@gmail.com
Cc: pang.xunlei@linaro.org
Cc: oleg@redhat.com
Cc: wanpeng.li@linux.intel.com
Cc: umgwanakikbuti@gmail.com
Link: http://lkml.kernel.org/r/20150611124742.766832367@infradead.org
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Byungchul Park <byungchul.park@lge.com>
Conflicts:
kernel/sched/rt.c
---
kernel/sched/rt.c | 35 +++++++++++++++++++----------------
1 file changed, 19 insertions(+), 16 deletions(-)
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index ce807aa..fe0399f 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -338,16 +338,23 @@ static inline int has_pushable_tasks(struct rq *rq)
return !plist_head_empty(&rq->rt.pushable_tasks);
}
-static DEFINE_PER_CPU(struct callback_head, rt_balance_head);
+static DEFINE_PER_CPU(struct callback_head, rt_push_head);
+static DEFINE_PER_CPU(struct callback_head, rt_pull_head);
static void push_rt_tasks(struct rq *);
+static void pull_rt_task(struct rq *);
static inline void queue_push_tasks(struct rq *rq)
{
if (!has_pushable_tasks(rq))
return;
- queue_balance_callback(rq, &per_cpu(rt_balance_head, rq->cpu), push_rt_tasks);
+ queue_balance_callback(rq, &per_cpu(rt_push_head, rq->cpu), push_rt_tasks);
+}
+
+static inline void queue_pull_task(struct rq *rq)
+{
+ queue_balance_callback(rq, &per_cpu(rt_pull_head, rq->cpu), pull_rt_task);
}
static void enqueue_pushable_task(struct rq *rq, struct task_struct *p)
@@ -1934,7 +1941,7 @@ static void switched_from_rt(struct rq *rq, struct task_struct *p)
if (!p->on_rq || rq->rt.rt_nr_running)
return;
- pull_rt_task(rq);
+ queue_pull_task(rq);
}
void __init init_sched_rt_class(void)
@@ -1955,8 +1962,6 @@ void __init init_sched_rt_class(void)
*/
static void switched_to_rt(struct rq *rq, struct task_struct *p)
{
- int check_resched = 1;
-
/*
* If we are already running, then there's nothing
* that needs to be done. But if we are not running
@@ -1966,13 +1971,12 @@ static void switched_to_rt(struct rq *rq, struct task_struct *p)
*/
if (p->on_rq && rq->curr != p) {
#ifdef CONFIG_SMP
- if (p->nr_cpus_allowed > 1 && rq->rt.overloaded &&
- /* Don't resched if we changed runqueues */
- push_rt_task(rq) && rq != task_rq(p))
- check_resched = 0;
-#endif /* CONFIG_SMP */
- if (check_resched && p->prio < rq->curr->prio)
+ if (p->nr_cpus_allowed > 1 && rq->rt.overloaded)
+ queue_push_tasks(rq);
+#else
+ if (p->prio < rq->curr->prio)
resched_curr(rq);
+#endif /* CONFIG_SMP */
}
}
@@ -1993,14 +1997,13 @@ prio_changed_rt(struct rq *rq, struct task_struct *p, int oldprio)
* may need to pull tasks to this runqueue.
*/
if (oldprio < p->prio)
- pull_rt_task(rq);
+ queue_pull_task(rq);
+
/*
* If there's a higher priority task waiting to run
- * then reschedule. Note, the above pull_rt_task
- * can release the rq lock and p could migrate.
- * Only reschedule if p is still on the same runqueue.
+ * then reschedule.
*/
- if (p->prio > rq->rt.highest_prio.curr && rq->curr == p)
+ if (p->prio > rq->rt.highest_prio.curr)
resched_curr(rq);
#else
/* For UP simply resched on drop of prio */
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Byungchul Park <byungchul.park@lge.com> |
|---|---|
| Date | 2016-01-05 10:30 +0100 |
| Subject | [PATCH for v3.18.25 6/6] sched, dl: Convert switched_{from, to}_dl() / prio_changed_dl() to balance callbacks |
| Message-ID | <qNw6e-5k-15@gated-at.bofh.it> |
| In reply to | #1301357 |
From: Peter Zijlstra <peterz@infradead.org>
Remove the direct {push,pull} balancing operations from
switched_{from,to}_dl() / prio_changed_dl() and use the balance
callback queue.
Again, err on the side of too many reschedules; since too few is a
hard bug while too many is just annoying.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: ktkhai@parallels.com
Cc: rostedt@goodmis.org
Cc: juri.lelli@gmail.com
Cc: pang.xunlei@linaro.org
Cc: oleg@redhat.com
Cc: wanpeng.li@linux.intel.com
Cc: umgwanakikbuti@gmail.com
Link: http://lkml.kernel.org/r/20150611124742.968262663@infradead.org
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Byungchul Park <byungchul.park@lge.com>
Conflicts:
kernel/sched/deadline.c
---
kernel/sched/deadline.c | 42 +++++++++++++++++++++++-------------------
1 file changed, 23 insertions(+), 19 deletions(-)
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
index 1242e5b..6762024 100644
--- a/kernel/sched/deadline.c
+++ b/kernel/sched/deadline.c
@@ -213,16 +213,23 @@ static inline bool need_pull_dl_task(struct rq *rq, struct task_struct *prev)
return dl_task(prev);
}
-static DEFINE_PER_CPU(struct callback_head, dl_balance_head);
+static DEFINE_PER_CPU(struct callback_head, dl_push_head);
+static DEFINE_PER_CPU(struct callback_head, dl_pull_head);
static void push_dl_tasks(struct rq *);
+static void pull_dl_task(struct rq *);
static inline void queue_push_tasks(struct rq *rq)
{
if (!has_pushable_dl_tasks(rq))
return;
- queue_balance_callback(rq, &per_cpu(dl_balance_head, rq->cpu), push_dl_tasks);
+ queue_balance_callback(rq, &per_cpu(dl_push_head, rq->cpu), push_dl_tasks);
+}
+
+static inline void queue_pull_task(struct rq *rq)
+{
+ queue_balance_callback(rq, &per_cpu(dl_pull_head, rq->cpu), pull_dl_task);
}
#else
@@ -259,6 +266,10 @@ static inline void pull_dl_task(struct rq *rq)
static inline void queue_push_tasks(struct rq *rq)
{
}
+
+static inline void queue_pull_task(struct rq *rq)
+{
+}
#endif /* CONFIG_SMP */
static void enqueue_task_dl(struct rq *rq, struct task_struct *p, int flags);
@@ -975,8 +986,6 @@ static void check_preempt_equal_dl(struct rq *rq, struct task_struct *p)
resched_curr(rq);
}
-static void pull_dl_task(struct rq *this_rq);
-
#endif /* CONFIG_SMP */
/*
@@ -1586,7 +1595,7 @@ static void switched_from_dl(struct rq *rq, struct task_struct *p)
* from an overloaded cpu, if any.
*/
if (!rq->dl.dl_nr_running)
- pull_dl_task(rq);
+ queue_pull_task(rq);
#endif
}
@@ -1596,8 +1605,6 @@ static void switched_from_dl(struct rq *rq, struct task_struct *p)
*/
static void switched_to_dl(struct rq *rq, struct task_struct *p)
{
- int check_resched = 1;
-
/*
* If p is throttled, don't consider the possibility
* of preempting rq->curr, the check will be done right
@@ -1608,16 +1615,14 @@ static void switched_to_dl(struct rq *rq, struct task_struct *p)
if (task_on_rq_queued(p) && rq->curr != p) {
#ifdef CONFIG_SMP
- if (rq->dl.overloaded && push_dl_task(rq) && rq != task_rq(p))
- /* Only reschedule if pushing failed */
- check_resched = 0;
+ if (rq->dl.overloaded)
+ queue_push_tasks(rq);
+#else
+ if (dl_task(rq->curr))
+ check_preempt_curr_dl(rq, p, 0);
+ else
+ resched_curr(rq);
#endif /* CONFIG_SMP */
- if (check_resched) {
- if (dl_task(rq->curr))
- check_preempt_curr_dl(rq, p, 0);
- else
- resched_curr(rq);
- }
}
}
@@ -1637,15 +1642,14 @@ static void prio_changed_dl(struct rq *rq, struct task_struct *p,
* or lowering its prio, so...
*/
if (!rq->dl.overloaded)
- pull_dl_task(rq);
+ queue_pull_task(rq);
/*
* If we now have a earlier deadline task than p,
* then reschedule, provided p is still on this
* runqueue.
*/
- if (dl_time_before(rq->dl.earliest_dl.curr, p->dl.deadline) &&
- rq->curr == p)
+ if (dl_time_before(rq->dl.earliest_dl.curr, p->dl.deadline))
resched_curr(rq);
#else
/*
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Byungchul Park <byungchul.park@lge.com> |
|---|---|
| Date | 2016-01-05 10:30 +0100 |
| Subject | [PATCH for v3.18.25 5/6] sched,dl: Remove return value from pull_dl_task() |
| Message-ID | <qNw6e-5k-19@gated-at.bofh.it> |
| In reply to | #1301357 |
From: Peter Zijlstra <peterz@infradead.org>
In order to be able to use pull_dl_task() from a callback, we need to
do away with the return value.
Since the return value indicates if we should reschedule, do this
inside the function. Since not all callers currently do this, this can
increase the number of reschedules due rt balancing.
Too many reschedules is not a correctness issues, too few are.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: ktkhai@parallels.com
Cc: rostedt@goodmis.org
Cc: juri.lelli@gmail.com
Cc: pang.xunlei@linaro.org
Cc: oleg@redhat.com
Cc: wanpeng.li@linux.intel.com
Cc: umgwanakikbuti@gmail.com
Link: http://lkml.kernel.org/r/20150611124742.859398977@infradead.org
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Byungchul Park <byungchul.park@lge.com>
Conflicts:
kernel/sched/deadline.c
---
kernel/sched/deadline.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
index 3bdf558..822b94f 100644
--- a/kernel/sched/deadline.c
+++ b/kernel/sched/deadline.c
@@ -252,9 +252,8 @@ static inline bool need_pull_dl_task(struct rq *rq, struct task_struct *prev)
return false;
}
-static inline int pull_dl_task(struct rq *rq)
+static inline void pull_dl_task(struct rq *rq)
{
- return 0;
}
static inline void queue_push_tasks(struct rq *rq)
@@ -974,7 +973,7 @@ static void check_preempt_equal_dl(struct rq *rq, struct task_struct *p)
resched_curr(rq);
}
-static int pull_dl_task(struct rq *this_rq);
+static void pull_dl_task(struct rq *this_rq);
#endif /* CONFIG_SMP */
@@ -1397,15 +1396,16 @@ static void push_dl_tasks(struct rq *rq)
;
}
-static int pull_dl_task(struct rq *this_rq)
+static void pull_dl_task(struct rq *this_rq)
{
- int this_cpu = this_rq->cpu, ret = 0, cpu;
+ int this_cpu = this_rq->cpu, cpu;
struct task_struct *p;
+ bool resched = false;
struct rq *src_rq;
u64 dmin = LONG_MAX;
if (likely(!dl_overloaded(this_rq)))
- return 0;
+ return;
/*
* Match the barrier from dl_set_overloaded; this guarantees that if we
@@ -1460,7 +1460,7 @@ static int pull_dl_task(struct rq *this_rq)
src_rq->curr->dl.deadline))
goto skip;
- ret = 1;
+ resched = true;
deactivate_task(src_rq, p, 0);
set_task_cpu(p, this_cpu);
@@ -1473,7 +1473,8 @@ skip:
double_unlock_balance(this_rq, src_rq);
}
- return ret;
+ if (resched)
+ resched_curr(this_rq);
}
/*
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Byungchul Park <byungchul.park@lge.com> |
|---|---|
| Date | 2016-01-05 10:30 +0100 |
| Subject | [PATCH for v3.18.25 2/6] sched: Allow balance callbacks for check_class_changed() |
| Message-ID | <qNw6e-5k-23@gated-at.bofh.it> |
| In reply to | #1301357 |
From: Peter Zijlstra <peterz@infradead.org>
In order to remove dropping rq->lock from the
switched_{to,from}()/prio_changed() sched_class methods, run the
balance callbacks after it.
We need to remove dropping rq->lock because its buggy,
suppose using sched_setattr()/sched_setscheduler() to change a running
task from FIFO to OTHER.
By the time we get to switched_from_rt() the task is already enqueued
on the cfs runqueues. If switched_from_rt() does pull_rt_task() and
drops rq->lock, load-balancing can come in and move our task @p to
another rq.
The subsequent switched_to_fair() still assumes @p is on @rq and bad
things will happen.
By using balance callbacks we delay the load-balancing operations
{rt,dl}x{push,pull} until we've done all the important work and the
task is fully set up.
Furthermore, the balance callbacks do not know about @p, therefore
they cannot get confused like this.
Reported-by: Mike Galbraith <umgwanakikbuti@gmail.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: ktkhai@parallels.com
Cc: rostedt@goodmis.org
Cc: juri.lelli@gmail.com
Cc: pang.xunlei@linaro.org
Cc: oleg@redhat.com
Cc: wanpeng.li@linux.intel.com
Link: http://lkml.kernel.org/r/20150611124742.615343911@infradead.org
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Byungchul Park <byungchul.park@lge.com>
Conflicts:
kernel/sched/core.c
---
kernel/sched/core.c | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 3dff0ef..ca6dad6 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -999,6 +999,13 @@ inline int task_curr(const struct task_struct *p)
return cpu_curr(task_cpu(p)) == p;
}
+/*
+ * switched_from, switched_to and prio_changed must _NOT_ drop rq->lock,
+ * use the balance_callback list if you want balancing.
+ *
+ * this means any call to check_class_changed() must be followed by a call to
+ * balance_callback().
+ */
static inline void check_class_changed(struct rq *rq, struct task_struct *p,
const struct sched_class *prev_class,
int oldprio)
@@ -1485,8 +1492,12 @@ ttwu_do_wakeup(struct rq *rq, struct task_struct *p, int wake_flags)
p->state = TASK_RUNNING;
#ifdef CONFIG_SMP
- if (p->sched_class->task_woken)
+ if (p->sched_class->task_woken) {
+ /*
+ * XXX can drop rq->lock; most likely ok.
+ */
p->sched_class->task_woken(rq, p);
+ }
if (rq->idle_stamp) {
u64 delta = rq_clock(rq) - rq->idle_stamp;
@@ -3032,7 +3043,11 @@ void rt_mutex_setprio(struct task_struct *p, int prio)
check_class_changed(rq, p, prev_class, oldprio);
out_unlock:
+ preempt_disable(); /* avoid rq from going away on us */
__task_rq_unlock(rq);
+
+ balance_callback(rq);
+ preempt_enable();
}
#endif
@@ -3559,10 +3574,17 @@ change:
}
check_class_changed(rq, p, prev_class, oldprio);
+ preempt_disable(); /* avoid rq from going away on us */
task_rq_unlock(rq, p, &flags);
rt_mutex_adjust_pi(p);
+ /*
+ * Run balance callbacks after we've adjusted the PI chain.
+ */
+ balance_callback(rq);
+ preempt_enable();
+
return 0;
}
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web