mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 03:36:19 +00:00
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>
This commit is contained in:
parent
c63a119036
commit
051a1d1afa
1 changed files with 11 additions and 6 deletions
|
@ -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)
|
||||||
#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)
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
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 @@ recheck:
|
||||||
}
|
}
|
||||||
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)
|
||||||
|
|
||||||
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) {
|
||||||
|
|
Loading…
Reference in a new issue