aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2011-09-12 07:06:17 -0400
committerIngo Molnar <mingo@elte.hu>2011-10-04 06:43:58 -0400
commitfa14ff4accfb24e59d2473f3d864d6648d80563b (patch)
treea2f3f5a16e1e740c6f96857e60c37826689d7b0b /kernel
parent924f8f5af31423529cc3940cb2ae9fee736b7517 (diff)
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>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/sched.c48
1 files changed, 10 insertions, 38 deletions
diff --git a/kernel/sched.c b/kernel/sched.c
index c5cf15e1eb57..1874c7418319 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -702,7 +702,7 @@ struct rq {
702#endif 702#endif
703 703
704#ifdef CONFIG_SMP 704#ifdef CONFIG_SMP
705 struct task_struct *wake_list; 705 struct llist_head wake_list;
706#endif 706#endif
707}; 707};
708 708
@@ -2698,42 +2698,26 @@ static int ttwu_remote(struct task_struct *p, int wake_flags)
2698} 2698}
2699 2699
2700#ifdef CONFIG_SMP 2700#ifdef CONFIG_SMP
2701static void sched_ttwu_do_pending(struct task_struct *list) 2701static void sched_ttwu_pending(void)
2702{ 2702{
2703 struct rq *rq = this_rq(); 2703 struct rq *rq = this_rq();
2704 struct llist_node *llist = llist_del_all(&rq->wake_list);
2705 struct task_struct *p;
2704 2706
2705 raw_spin_lock(&rq->lock); 2707 raw_spin_lock(&rq->lock);
2706 2708
2707 while (list) { 2709 while (llist) {
2708 struct task_struct *p = list; 2710 p = llist_entry(llist, struct task_struct, wake_entry);
2709 list = list->wake_entry; 2711 llist = llist_next(llist);
2710 ttwu_do_activate(rq, p, 0); 2712 ttwu_do_activate(rq, p, 0);
2711 } 2713 }
2712 2714
2713 raw_spin_unlock(&rq->lock); 2715 raw_spin_unlock(&rq->lock);
2714} 2716}
2715 2717
2716#ifdef CONFIG_HOTPLUG_CPU
2717
2718static void sched_ttwu_pending(void)
2719{
2720 struct rq *rq = this_rq();
2721 struct task_struct *list = xchg(&rq->wake_list, NULL);
2722
2723 if (!list)
2724 return;
2725
2726 sched_ttwu_do_pending(list);
2727}
2728
2729#endif /* CONFIG_HOTPLUG_CPU */
2730
2731void scheduler_ipi(void) 2718void scheduler_ipi(void)
2732{ 2719{
2733 struct rq *rq = this_rq(); 2720 if (llist_empty(&this_rq()->wake_list))
2734 struct task_struct *list = xchg(&rq->wake_list, NULL);
2735
2736 if (!list)
2737 return; 2721 return;
2738 2722
2739 /* 2723 /*
@@ -2750,25 +2734,13 @@ void scheduler_ipi(void)
2750 * somewhat pessimize the simple resched case. 2734 * somewhat pessimize the simple resched case.
2751 */ 2735 */
2752 irq_enter(); 2736 irq_enter();
2753 sched_ttwu_do_pending(list); 2737 sched_ttwu_pending();
2754 irq_exit(); 2738 irq_exit();
2755} 2739}
2756 2740
2757static void ttwu_queue_remote(struct task_struct *p, int cpu) 2741static void ttwu_queue_remote(struct task_struct *p, int cpu)
2758{ 2742{
2759 struct rq *rq = cpu_rq(cpu); 2743 if (llist_add(&p->wake_entry, &cpu_rq(cpu)->wake_list))
2760 struct task_struct *next = rq->wake_list;
2761
2762 for (;;) {
2763 struct task_struct *old = next;
2764
2765 p->wake_entry = next;
2766 next = cmpxchg(&rq->wake_list, old, p);
2767 if (next == old)
2768 break;
2769 }
2770
2771 if (!next)
2772 smp_send_reschedule(cpu); 2744 smp_send_reschedule(cpu);
2773} 2745}
2774 2746