sched: Convert to struct llist
Use the generic llist primitives. We had a private lockless list implementation in the scheduler in the wake-list code, now that we have a generic llist implementation that provides all required operations, switch to it. This patch is not expected to change any behavior. Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Huang Ying <ying.huang@intel.com> Cc: Andrew Morton <akpm@linux-foundation.org> Link: http://lkml.kernel.org/r/1315836353.26517.42.camel@twins Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
parent
924f8f5af3
commit
fa14ff4acc
|
@ -90,6 +90,7 @@ struct sched_param {
|
||||||
#include <linux/task_io_accounting.h>
|
#include <linux/task_io_accounting.h>
|
||||||
#include <linux/latencytop.h>
|
#include <linux/latencytop.h>
|
||||||
#include <linux/cred.h>
|
#include <linux/cred.h>
|
||||||
|
#include <linux/llist.h>
|
||||||
|
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
|
|
||||||
|
@ -1225,7 +1226,7 @@ struct task_struct {
|
||||||
unsigned int ptrace;
|
unsigned int ptrace;
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
struct task_struct *wake_entry;
|
struct llist_node wake_entry;
|
||||||
int on_cpu;
|
int on_cpu;
|
||||||
#endif
|
#endif
|
||||||
int on_rq;
|
int on_rq;
|
||||||
|
|
|
@ -702,7 +702,7 @@ struct rq {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
struct task_struct *wake_list;
|
struct llist_head wake_list;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2698,42 +2698,26 @@ static int ttwu_remote(struct task_struct *p, int wake_flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
static void sched_ttwu_do_pending(struct task_struct *list)
|
static void sched_ttwu_pending(void)
|
||||||
{
|
{
|
||||||
struct rq *rq = this_rq();
|
struct rq *rq = this_rq();
|
||||||
|
struct llist_node *llist = llist_del_all(&rq->wake_list);
|
||||||
|
struct task_struct *p;
|
||||||
|
|
||||||
raw_spin_lock(&rq->lock);
|
raw_spin_lock(&rq->lock);
|
||||||
|
|
||||||
while (list) {
|
while (llist) {
|
||||||
struct task_struct *p = list;
|
p = llist_entry(llist, struct task_struct, wake_entry);
|
||||||
list = list->wake_entry;
|
llist = llist_next(llist);
|
||||||
ttwu_do_activate(rq, p, 0);
|
ttwu_do_activate(rq, p, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
raw_spin_unlock(&rq->lock);
|
raw_spin_unlock(&rq->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_HOTPLUG_CPU
|
|
||||||
|
|
||||||
static void sched_ttwu_pending(void)
|
|
||||||
{
|
|
||||||
struct rq *rq = this_rq();
|
|
||||||
struct task_struct *list = xchg(&rq->wake_list, NULL);
|
|
||||||
|
|
||||||
if (!list)
|
|
||||||
return;
|
|
||||||
|
|
||||||
sched_ttwu_do_pending(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* CONFIG_HOTPLUG_CPU */
|
|
||||||
|
|
||||||
void scheduler_ipi(void)
|
void scheduler_ipi(void)
|
||||||
{
|
{
|
||||||
struct rq *rq = this_rq();
|
if (llist_empty(&this_rq()->wake_list))
|
||||||
struct task_struct *list = xchg(&rq->wake_list, NULL);
|
|
||||||
|
|
||||||
if (!list)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2750,25 +2734,13 @@ void scheduler_ipi(void)
|
||||||
* somewhat pessimize the simple resched case.
|
* somewhat pessimize the simple resched case.
|
||||||
*/
|
*/
|
||||||
irq_enter();
|
irq_enter();
|
||||||
sched_ttwu_do_pending(list);
|
sched_ttwu_pending();
|
||||||
irq_exit();
|
irq_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ttwu_queue_remote(struct task_struct *p, int cpu)
|
static void ttwu_queue_remote(struct task_struct *p, int cpu)
|
||||||
{
|
{
|
||||||
struct rq *rq = cpu_rq(cpu);
|
if (llist_add(&p->wake_entry, &cpu_rq(cpu)->wake_list))
|
||||||
struct task_struct *next = rq->wake_list;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
struct task_struct *old = next;
|
|
||||||
|
|
||||||
p->wake_entry = next;
|
|
||||||
next = cmpxchg(&rq->wake_list, old, p);
|
|
||||||
if (next == old)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!next)
|
|
||||||
smp_send_reschedule(cpu);
|
smp_send_reschedule(cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue