Commit 051a1d1a authored by Dmitry Adamushko's avatar Dmitry Adamushko Committed by Ingo Molnar

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.htmlSigned-off-by: default avatarDmitry Adamushko <dmitry.adamushko@gmail.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Tested-by: default avatarDhaval Giani <dhaval@linux.vnet.ibm.com>
Tested-by: default avatarKAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
parent c63a1190
...@@ -508,10 +508,15 @@ EXPORT_SYMBOL_GPL(cpu_clock); ...@@ -508,10 +508,15 @@ EXPORT_SYMBOL_GPL(cpu_clock);
# define finish_arch_switch(prev) do { } while (0) # define finish_arch_switch(prev) do { } while (0)
#endif #endif
static inline int task_current(struct rq *rq, struct task_struct *p)
{
return rq->curr == p;
}
#ifndef __ARCH_WANT_UNLOCKED_CTXSW #ifndef __ARCH_WANT_UNLOCKED_CTXSW
static inline int task_running(struct rq *rq, struct task_struct *p) static inline int task_running(struct rq *rq, struct task_struct *p)
{ {
return rq->curr == p; return task_current(rq, p);
} }
static inline void prepare_lock_switch(struct rq *rq, struct task_struct *next) 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,7 +545,7 @@ static inline int task_running(struct rq *rq, struct task_struct *p)
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
return p->oncpu; return p->oncpu;
#else #else
return rq->curr == p; return task_current(rq, p);
#endif #endif
} }
...@@ -3334,7 +3339,7 @@ unsigned long long task_sched_runtime(struct task_struct *p) ...@@ -3334,7 +3339,7 @@ unsigned long long task_sched_runtime(struct task_struct *p)
rq = task_rq_lock(p, &flags); rq = task_rq_lock(p, &flags);
ns = p->se.sum_exec_runtime; ns = p->se.sum_exec_runtime;
if (rq->curr == p) { if (task_current(rq, p)) {
update_rq_clock(rq); update_rq_clock(rq);
delta_exec = rq->clock - p->se.exec_start; delta_exec = rq->clock - p->se.exec_start;
if ((s64)delta_exec > 0) if ((s64)delta_exec > 0)
...@@ -4021,7 +4026,7 @@ void rt_mutex_setprio(struct task_struct *p, int prio) ...@@ -4021,7 +4026,7 @@ void rt_mutex_setprio(struct task_struct *p, int prio)
oldprio = p->prio; oldprio = p->prio;
on_rq = p->se.on_rq; on_rq = p->se.on_rq;
running = task_running(rq, p); running = task_current(rq, p);
if (on_rq) { if (on_rq) {
dequeue_task(rq, p, 0); dequeue_task(rq, p, 0);
if (running) if (running)
...@@ -4332,7 +4337,7 @@ int sched_setscheduler(struct task_struct *p, int policy, ...@@ -4332,7 +4337,7 @@ int sched_setscheduler(struct task_struct *p, int policy,
} }
update_rq_clock(rq); update_rq_clock(rq);
on_rq = p->se.on_rq; on_rq = p->se.on_rq;
running = task_running(rq, p); running = task_current(rq, p);
if (on_rq) { if (on_rq) {
deactivate_task(rq, p, 0); deactivate_task(rq, p, 0);
if (running) if (running)
...@@ -7101,7 +7106,7 @@ void sched_move_task(struct task_struct *tsk) ...@@ -7101,7 +7106,7 @@ void sched_move_task(struct task_struct *tsk)
update_rq_clock(rq); update_rq_clock(rq);
running = task_running(rq, tsk); running = task_current(rq, tsk);
on_rq = tsk->se.on_rq; on_rq = tsk->se.on_rq;
if (on_rq) { if (on_rq) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment