diff options
author | Dmitry Adamushko <dmitry.adamushko@gmail.com> | 2007-12-18 09:21:13 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2007-12-18 09:21:13 -0500 |
commit | 051a1d1afa47206e23ae03f781c6795ce870e3d5 (patch) | |
tree | 6ce53c173a3a7582896504ecfc758e993455e5fb /kernel/sched.c | |
parent | c63a1190368771b8207d86c4217ae4afdf1cbd5e (diff) |
sched: fix crash on ia64, introduce task_current()
Some services (e.g. sched_setscheduler(), rt_mutex_setprio() and
sched_move_task()) must handle a given task differently in case it's the
'rq->curr' task on its run-queue. The task_running() interface is not
suitable for determining such tasks for platforms with one of the
following options:
#define __ARCH_WANT_UNLOCKED_CTXSW
#define __ARCH_WANT_INTERRUPTS_ON_CTXSW
Due to the fact that it makes use of 'p->oncpu == 1' as a criterion but
such a task is not necessarily 'rq->curr'.
The detailed explanation is available here:
https://lists.linux-foundation.org/pipermail/containers/2007-December/009262.html
Signed-off-by: Dmitry Adamushko <dmitry.adamushko@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Tested-by: Dhaval Giani <dhaval@linux.vnet.ibm.com>
Tested-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Diffstat (limited to 'kernel/sched.c')
-rw-r--r-- | kernel/sched.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index c6e551de795b..5ae0d4296e7c 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -508,10 +508,15 @@ EXPORT_SYMBOL_GPL(cpu_clock); | |||
508 | # define finish_arch_switch(prev) do { } while (0) | 508 | # define finish_arch_switch(prev) do { } while (0) |
509 | #endif | 509 | #endif |
510 | 510 | ||
511 | static inline int task_current(struct rq *rq, struct task_struct *p) | ||
512 | { | ||
513 | return rq->curr == p; | ||
514 | } | ||
515 | |||
511 | #ifndef __ARCH_WANT_UNLOCKED_CTXSW | 516 | #ifndef __ARCH_WANT_UNLOCKED_CTXSW |
512 | static inline int task_running(struct rq *rq, struct task_struct *p) | 517 | static inline int task_running(struct rq *rq, struct task_struct *p) |
513 | { | 518 | { |
514 | return rq->curr == p; | 519 | return task_current(rq, p); |
515 | } | 520 | } |
516 | 521 | ||
517 | static inline void prepare_lock_switch(struct rq *rq, struct task_struct *next) | 522 | static inline void prepare_lock_switch(struct rq *rq, struct task_struct *next) |
@@ -540,7 +545,7 @@ static inline int task_running(struct rq *rq, struct task_struct *p) | |||
540 | #ifdef CONFIG_SMP | 545 | #ifdef CONFIG_SMP |
541 | return p->oncpu; | 546 | return p->oncpu; |
542 | #else | 547 | #else |
543 | return rq->curr == p; | 548 | return task_current(rq, p); |
544 | #endif | 549 | #endif |
545 | } | 550 | } |
546 | 551 | ||
@@ -3334,7 +3339,7 @@ unsigned long long task_sched_runtime(struct task_struct *p) | |||
3334 | 3339 | ||
3335 | rq = task_rq_lock(p, &flags); | 3340 | rq = task_rq_lock(p, &flags); |
3336 | ns = p->se.sum_exec_runtime; | 3341 | ns = p->se.sum_exec_runtime; |
3337 | if (rq->curr == p) { | 3342 | if (task_current(rq, p)) { |
3338 | update_rq_clock(rq); | 3343 | update_rq_clock(rq); |
3339 | delta_exec = rq->clock - p->se.exec_start; | 3344 | delta_exec = rq->clock - p->se.exec_start; |
3340 | if ((s64)delta_exec > 0) | 3345 | if ((s64)delta_exec > 0) |
@@ -4021,7 +4026,7 @@ void rt_mutex_setprio(struct task_struct *p, int prio) | |||
4021 | 4026 | ||
4022 | oldprio = p->prio; | 4027 | oldprio = p->prio; |
4023 | on_rq = p->se.on_rq; | 4028 | on_rq = p->se.on_rq; |
4024 | running = task_running(rq, p); | 4029 | running = task_current(rq, p); |
4025 | if (on_rq) { | 4030 | if (on_rq) { |
4026 | dequeue_task(rq, p, 0); | 4031 | dequeue_task(rq, p, 0); |
4027 | if (running) | 4032 | if (running) |
@@ -4332,7 +4337,7 @@ recheck: | |||
4332 | } | 4337 | } |
4333 | update_rq_clock(rq); | 4338 | update_rq_clock(rq); |
4334 | on_rq = p->se.on_rq; | 4339 | on_rq = p->se.on_rq; |
4335 | running = task_running(rq, p); | 4340 | running = task_current(rq, p); |
4336 | if (on_rq) { | 4341 | if (on_rq) { |
4337 | deactivate_task(rq, p, 0); | 4342 | deactivate_task(rq, p, 0); |
4338 | if (running) | 4343 | if (running) |
@@ -7101,7 +7106,7 @@ void sched_move_task(struct task_struct *tsk) | |||
7101 | 7106 | ||
7102 | update_rq_clock(rq); | 7107 | update_rq_clock(rq); |
7103 | 7108 | ||
7104 | running = task_running(rq, tsk); | 7109 | running = task_current(rq, tsk); |
7105 | on_rq = tsk->se.on_rq; | 7110 | on_rq = tsk->se.on_rq; |
7106 | 7111 | ||
7107 | if (on_rq) { | 7112 | if (on_rq) { |