On Sat, 2007-10-13 at 11:17 +0200, Peter Zijlstra wrote:I guess something like this ought to do, but its a tad late so I'm quite sure :-) --- kernel/sched_fair.c | 44 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-) Index: linux-2.6/kernel/sched_fair.c =================================================================== --- linux-2.6.orig/kernel/sched_fair.c +++ linux-2.6/kernel/sched_fair.c @@ -737,6 +737,24 @@ static inline struct sched_entity *paren #endif /* CONFIG_FAIR_GROUP_SCHED */ +/* + * does pse (newly woken task) preempt se (current task) + */ +static int wakeup_preempt(struct sched_entity *se, struct sched_entity *pse) +{ + s64 delta, gran; + + delta = se->vruntime - pse->vruntime; + gran = sysctl_sched_wakeup_granularity; + if (unlikely(se->load.weight != NICE_0_LOAD)) + gran = calc_delta_fair(gran, &se->load); + + if (delta > gran) + return 1; + + return 0; +} + #ifdef CONFIG_SCHED_HRTICK static void hrtick_start_fair(struct rq *rq, struct task_struct *p) { @@ -764,6 +782,24 @@ static void hrtick_start_fair(struct rq if (!requeue) delta = max(10000LL, delta); + /* + * if we delayed wakeup preemption, shorten the slice to at most + * 1 jiffy (does this call for yet another sysctl_sched_?) + */ + if (sched_feat(PREEMPT_RESTRICT) && first_fair(cfs_rq)) { + struct sched_entity *next = __pick_next_entity(cfs_rq); + + if (wakeup_preempt(se, next)) { + u64 wakeup = NSEC_PER_SEC / HZ; + s64 delta2 = wakeup - ran; + + if (delta2 < 0) + resched_task(rq->curr); + else + delta = min(delta, delta2); + } + } + hrtick_start(rq, delta, requeue); } } @@ -866,7 +902,6 @@ static void check_preempt_wakeup(struct struct task_struct *curr = rq->curr; struct cfs_rq *cfs_rq = task_cfs_rq(curr); struct sched_entity *se = &curr->se, *pse = &p->se; - s64 delta, gran; if (unlikely(rt_prio(p->prio))) { update_rq_clock(rq); @@ -887,12 +922,7 @@ static void check_preempt_wakeup(struct pse = parent_entity(pse); } - delta = se->vruntime - pse->vruntime; - gran = sysctl_sched_wakeup_granularity; - if (unlikely(se->load.weight != NICE_0_LOAD)) - gran = calc_delta_fair(gran, &se->load); - - if (delta > gran) { + if (wakeup_preempt(se, pse)) { int now = !sched_feat(PREEMPT_RESTRICT); if (now || p->prio < curr->prio || !se->peer_preempt++) -
| Theodore Tso | Re: -mm merge plans for 2.6.23 -- sys_fallocate |
| Amit K. Arora | [RFC] Heads up on sys_fallocate() |
| Tarkan Erimer | Re: Dual-Licensing Linux Kernel with GPL V2 and GPL V3 |
| Greg Kroah-Hartman | [PATCH 011/196] sysfs: Fix a copy-n-paste typo in comment |
git: | |
| Jarek Poplawski | Re: [PATCH] pkt_sched: Destroy gen estimators under rtnl_lock(). |
| David Miller | Re: [GIT]: Networking |
| Gerrit Renker | [PATCH 27/37] dccp: Integration of dynamic feature activation - part 2 (server side) |
| Frans Pop | svc: failed to register lockdv1 RPC service (errno 97). |
