lkml.org 
[lkml]   [2007]   [Dec]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[git pull] scheduler fixes

    * Ingo Molnar <mingo@elte.hu> wrote:

    > The problem is on SMP: if sched_rr_get_interval() gets a task from an
    > otherwise idle runqueue, then rq->load.weight is 0. Normally
    > sched_slice() is only used on a busy runqueue. So the correct fixup
    > site is not in sched_slice() but in sys_sched_rr_get_interval() - i'm
    > working on the right fix, i hope to be able to send a pull request in
    > a few minutes.

    the problem is on UP too - if there are no SCHED_OTHER tasks. I've
    tested the fix and it solves the problem for various combinations of
    crash.c. I've updated sched.git, please pull it from:

    git://git.kernel.org/pub/scm/linux/kernel/git/mingo/linux-2.6-sched.git

    It has another commit besides this fix. Thanks,

    Ingo

    ------------------>

    Ingo Molnar (2):
    sched: fix crash in sys_sched_rr_get_interval()
    sched: default to more agressive yield for SCHED_BATCH tasks

    sched.c | 14 +++++++++-----
    sched_fair.c | 7 ++++---
    2 files changed, 13 insertions(+), 8 deletions(-)

    diff --git a/kernel/sched.c b/kernel/sched.c
    index 59ff6b1..b062856 100644
    --- a/kernel/sched.c
    +++ b/kernel/sched.c
    @@ -4850,17 +4850,21 @@ long sys_sched_rr_get_interval(pid_t pid, struct timespec __user *interval)
    if (retval)
    goto out_unlock;

    - if (p->policy == SCHED_FIFO)
    - time_slice = 0;
    - else if (p->policy == SCHED_RR)
    + /*
    + * Time slice is 0 for SCHED_FIFO tasks and for SCHED_OTHER
    + * tasks that are on an otherwise idle runqueue:
    + */
    + time_slice = 0;
    + if (p->policy == SCHED_RR) {
    time_slice = DEF_TIMESLICE;
    - else {
    + } else {
    struct sched_entity *se = &p->se;
    unsigned long flags;
    struct rq *rq;

    rq = task_rq_lock(p, &flags);
    - time_slice = NS_TO_JIFFIES(sched_slice(cfs_rq_of(se), se));
    + if (rq->cfs.load.weight)
    + time_slice = NS_TO_JIFFIES(sched_slice(&rq->cfs, se));
    task_rq_unlock(rq, &flags);
    }
    read_unlock(&tasklist_lock);
    diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
    index 37bb265..c33f0ce 100644
    --- a/kernel/sched_fair.c
    +++ b/kernel/sched_fair.c
    @@ -799,8 +799,9 @@ static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int sleep)
    */
    static void yield_task_fair(struct rq *rq)
    {
    - struct cfs_rq *cfs_rq = task_cfs_rq(rq->curr);
    - struct sched_entity *rightmost, *se = &rq->curr->se;
    + struct task_struct *curr = rq->curr;
    + struct cfs_rq *cfs_rq = task_cfs_rq(curr);
    + struct sched_entity *rightmost, *se = &curr->se;

    /*
    * Are we the only task in the tree?
    @@ -808,7 +809,7 @@ static void yield_task_fair(struct rq *rq)
    if (unlikely(cfs_rq->nr_running == 1))
    return;

    - if (likely(!sysctl_sched_compat_yield)) {
    + if (likely(!sysctl_sched_compat_yield) && curr->policy != SCHED_BATCH) {
    __update_rq_clock(rq);
    /*
    * Update run-time statistics of the 'current'.

    \
     
     \ /
      Last update: 2007-12-04 17:21    [W:0.029 / U:34.048 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site