diff options
-rw-r--r-- | include/linux/sched.h | 1 | ||||
-rw-r--r-- | kernel/sched/core.c | 18 |
2 files changed, 19 insertions, 0 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h index 674989708591..e23f8202c2bd 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1939,6 +1939,7 @@ extern int task_nice(const struct task_struct *p); extern int can_nice(const struct task_struct *p, const int nice); extern int task_curr(const struct task_struct *p); extern int idle_cpu(int cpu); +extern int idle_cpu_relaxed(int cpu); extern int sched_setscheduler(struct task_struct *, int, const struct sched_param *); extern int sched_setscheduler_nocheck(struct task_struct *, int, diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 3bfa39888f70..181767968d6c 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -81,6 +81,7 @@ #include <asm/tlb.h> #include <asm/irq_regs.h> #include <asm/mutex.h> +#include <asm/relaxed.h> #ifdef CONFIG_PARAVIRT #include <asm/paravirt.h> #endif @@ -3855,6 +3856,23 @@ int idle_cpu(int cpu) return 1; } +int idle_cpu_relaxed(int cpu) +{ + struct rq *rq = cpu_rq(cpu); + + if (cpu_relaxed_read_long(&rq->curr) != rq->idle) + return 0; + + if (cpu_relaxed_read_long(&rq->nr_running)) + return 0; + +#ifdef CONFIG_SMP + if (!llist_empty_relaxed(&rq->wake_list)) + return 0; +#endif + + return 1; +} /** * idle_task - return the idle task for a given cpu. * @cpu: the processor in question. |