aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2009-11-28 12:51:02 -0500
committerIngo Molnar <mingo@elte.hu>2009-12-09 04:03:07 -0500
commit3a7e73a2e26fffdbc46ba95fc0425418984f5140 (patch)
tree02fdd1c081acfde7522a971bc2969bca76ca90c7
parenta65ac745e47e91f9d98dbf07f22ed0492e34d998 (diff)
sched: Clean up check_preempt_wakeup()
Streamline the wakeup preemption code a bit, unifying the preempt path so that they all do the same. Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> LKML-Reference: <new-submission> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--kernel/sched_fair.c73
1 files changed, 33 insertions, 40 deletions
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
index 4dec18579c9a..76b5792c4198 100644
--- a/kernel/sched_fair.c
+++ b/kernel/sched_fair.c
@@ -1651,10 +1651,8 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_
1651 int sync = wake_flags & WF_SYNC; 1651 int sync = wake_flags & WF_SYNC;
1652 int scale = cfs_rq->nr_running >= sched_nr_latency; 1652 int scale = cfs_rq->nr_running >= sched_nr_latency;
1653 1653
1654 if (unlikely(rt_prio(p->prio))) { 1654 if (unlikely(rt_prio(p->prio)))
1655 resched_task(curr); 1655 goto preempt;
1656 return;
1657 }
1658 1656
1659 if (unlikely(p->sched_class != &fair_sched_class)) 1657 if (unlikely(p->sched_class != &fair_sched_class))
1660 return; 1658 return;
@@ -1680,52 +1678,47 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_
1680 return; 1678 return;
1681 1679
1682 /* Idle tasks are by definition preempted by everybody. */ 1680 /* Idle tasks are by definition preempted by everybody. */
1683 if (unlikely(curr->policy == SCHED_IDLE)) { 1681 if (unlikely(curr->policy == SCHED_IDLE))
1684 resched_task(curr); 1682 goto preempt;
1685 return;
1686 }
1687 1683
1688 if ((sched_feat(WAKEUP_SYNC) && sync) || 1684 if (sched_feat(WAKEUP_SYNC) && sync)
1689 (sched_feat(WAKEUP_OVERLAP) && 1685 goto preempt;
1690 (se->avg_overlap < sysctl_sched_migration_cost &&
1691 pse->avg_overlap < sysctl_sched_migration_cost))) {
1692 resched_task(curr);
1693 return;
1694 }
1695 1686
1696 if (sched_feat(WAKEUP_RUNNING)) { 1687 if (sched_feat(WAKEUP_OVERLAP) &&
1697 if (pse->avg_running < se->avg_running) { 1688 se->avg_overlap < sysctl_sched_migration_cost &&
1698 set_next_buddy(pse); 1689 pse->avg_overlap < sysctl_sched_migration_cost)
1699 resched_task(curr); 1690 goto preempt;
1700 return; 1691
1701 } 1692 if (sched_feat(WAKEUP_RUNNING) && pse->avg_running < se->avg_running)
1702 } 1693 goto preempt;
1703 1694
1704 if (!sched_feat(WAKEUP_PREEMPT)) 1695 if (!sched_feat(WAKEUP_PREEMPT))
1705 return; 1696 return;
1706 1697
1698 update_curr(cfs_rq);
1707 find_matching_se(&se, &pse); 1699 find_matching_se(&se, &pse);
1708
1709 BUG_ON(!pse); 1700 BUG_ON(!pse);
1701 if (wakeup_preempt_entity(se, pse) == 1)
1702 goto preempt;
1710 1703
1711 update_curr(cfs_rq); 1704 return;
1712 1705
1713 if (wakeup_preempt_entity(se, pse) == 1) { 1706preempt:
1714 resched_task(curr); 1707 resched_task(curr);
1715 /* 1708 /*
1716 * Only set the backward buddy when the current task is still 1709 * Only set the backward buddy when the current task is still
1717 * on the rq. This can happen when a wakeup gets interleaved 1710 * on the rq. This can happen when a wakeup gets interleaved
1718 * with schedule on the ->pre_schedule() or idle_balance() 1711 * with schedule on the ->pre_schedule() or idle_balance()
1719 * point, either of which can * drop the rq lock. 1712 * point, either of which can * drop the rq lock.
1720 * 1713 *
1721 * Also, during early boot the idle thread is in the fair class, 1714 * Also, during early boot the idle thread is in the fair class,
1722 * for obvious reasons its a bad idea to schedule back to it. 1715 * for obvious reasons its a bad idea to schedule back to it.
1723 */ 1716 */
1724 if (unlikely(!se->on_rq || curr == rq->idle)) 1717 if (unlikely(!se->on_rq || curr == rq->idle))
1725 return; 1718 return;
1726 if (sched_feat(LAST_BUDDY) && scale && entity_is_task(se)) 1719
1727 set_last_buddy(se); 1720 if (sched_feat(LAST_BUDDY) && scale && entity_is_task(se))
1728 } 1721 set_last_buddy(se);
1729} 1722}
1730 1723
1731static struct task_struct *pick_next_task_fair(struct rq *rq) 1724static struct task_struct *pick_next_task_fair(struct rq *rq)