lkml.org 
[lkml]   [2009]   [May]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [RFC][PATCH] Multimedia scheduling class, take 2
    Hi,

    Peter Zijlstra wrote:
    > Right, and I think the solution to this problem is twofold, 1)
    > application writers should start writing (soft) realtime applications if
    > they want (soft) realtime behaviour -- there's just no way around that.

    Just to avoid need for reviewing and reworking ~800 klocs of user space
    code in just gstreamer, here's a second take on patches. This time
    splitting things into smaller pieces. Attached patch exposes 40
    priorities ~ nice values as something accessible through
    sched_()/pthreads API in order to control priorities of individual
    threads. Current Linux implementation of SCHED_OTHER is broken in a way,
    that it exposes only one single priority level - 0. Thus no possibility
    to properly control priorities of threads through pthread API. This is
    patch is against 2.6.29.2 and not tested, but builds. I can also send
    rest of the changes as separate small feature patches as needed.
    However, before doing any more work I would like to hear opinions on
    this and especially what is wrong with the code or idea...

    > And 2), the kernel can help by providing a deadline based scheduler,
    > which should make the above easier and less likely to mess up the rest
    > of the system. ie. a deadline scheduled application will not exceed its
    > allotted budget, unlike a FIFO scheduled app.

    Any news on this one?


    - Jussi
    diff -urN linux-2.6.29.2.orig/include/linux/sched.h linux-2.6.29.2.new/include/linux/sched.h
    --- linux-2.6.29.2.orig/include/linux/sched.h 2009-04-27 20:37:11.000000000 +0300
    +++ linux-2.6.29.2.new/include/linux/sched.h 2009-05-11 11:02:26.000000000 +0300
    @@ -38,6 +38,7 @@
    #define SCHED_BATCH 3
    /* SCHED_ISO: reserved but not implemented yet */
    #define SCHED_IDLE 5
    +#define SCHED_MM 6

    #ifdef __KERNEL__

    diff -urN linux-2.6.29.2.orig/kernel/sched.c linux-2.6.29.2.new/kernel/sched.c
    --- linux-2.6.29.2.orig/kernel/sched.c 2009-04-27 20:37:11.000000000 +0300
    +++ linux-2.6.29.2.new/kernel/sched.c 2009-05-11 11:02:26.000000000 +0300
    @@ -24,6 +24,7 @@
    * 2007-07-01 Group scheduling enhancements by Srivatsa Vaddagiri
    * 2007-11-29 RT balancing improvements by Steven Rostedt, Gregory Haskins,
    * Thomas Gleixner, Mike Kravetz
    + * 2008-12-22 Multimedia scheduling class by Jussi Laako.
    */

    #include <linux/mm.h>
    @@ -98,6 +99,14 @@
    #define MAX_USER_PRIO (USER_PRIO(MAX_PRIO))

    /*
    + * User definable priorities for SCHED_MM.
    + */
    +#define MM_PRIO_MIN 0
    +#define MM_PRIO_MAX 39
    +#define INV_MM_PRIO(p) (39-(p))
    +#define STATIC_PRIO(p) ((p)+MAX_RT_PRIO)
    +
    +/*
    * Helpers for converting nanosecond timing to jiffy resolution
    */
    #define NS_TO_JIFFIES(TIME) ((unsigned long)(TIME) / (NSEC_PER_SEC / HZ))
    @@ -160,6 +169,18 @@
    return rt_policy(p->policy);
    }

    +static inline int mm_policy(int policy)
    +{
    + if (unlikely(policy == SCHED_MM))
    + return 1;
    + return 0;
    +}
    +
    +static inline int task_has_mm_policy(struct task_struct *p)
    +{
    + return mm_policy(p->policy);
    +}
    +
    /*
    * This is the priority-queue data structure of the RT scheduling class:
    */
    @@ -5282,6 +5303,7 @@
    case SCHED_NORMAL:
    case SCHED_BATCH:
    case SCHED_IDLE:
    + case SCHED_MM:
    p->sched_class = &fair_sched_class;
    break;
    case SCHED_FIFO:
    @@ -5292,6 +5314,8 @@

    p->rt_priority = prio;
    p->normal_prio = normal_prio(p);
    + if (task_has_mm_policy(p))
    + p->static_prio = prio;
    /* we are holding p->pi_lock already */
    p->prio = rt_mutex_getprio(p);
    set_load_weight(p);
    @@ -5329,19 +5353,26 @@
    policy = oldpolicy = p->policy;
    else if (policy != SCHED_FIFO && policy != SCHED_RR &&
    policy != SCHED_NORMAL && policy != SCHED_BATCH &&
    - policy != SCHED_IDLE)
    + policy != SCHED_IDLE && policy != SCHED_MM)
    return -EINVAL;
    /*
    * Valid priorities for SCHED_FIFO and SCHED_RR are
    * 1..MAX_USER_RT_PRIO-1, valid priority for SCHED_NORMAL,
    * SCHED_BATCH and SCHED_IDLE is 0.
    + * SCHED_MM has valid range from MM_PRIO_MIN to MM_PRIO_MAX.
    */
    - if (param->sched_priority < 0 ||
    - (p->mm && param->sched_priority > MAX_USER_RT_PRIO-1) ||
    - (!p->mm && param->sched_priority > MAX_RT_PRIO-1))
    - return -EINVAL;
    - if (rt_policy(policy) != (param->sched_priority != 0))
    - return -EINVAL;
    + if (mm_policy(policy)) {
    + if (param->sched_priority < MM_PRIO_MIN ||
    + param->sched_priority > MM_PRIO_MAX)
    + return -EINVAL;
    + } else {
    + if (param->sched_priority < 0 ||
    + (p->mm && param->sched_priority > MAX_USER_RT_PRIO-1) ||
    + (!p->mm && param->sched_priority > MAX_RT_PRIO-1))
    + return -EINVAL;
    + if (rt_policy(policy) != (param->sched_priority != 0))
    + return -EINVAL;
    + }

    /*
    * Allow unprivileged RT tasks to decrease priority:
    @@ -5418,7 +5449,11 @@
    p->sched_class->put_prev_task(rq, p);

    oldprio = p->prio;
    - __setscheduler(rq, p, policy, param->sched_priority);
    + if (mm_policy(policy))
    + __setscheduler(rq, p, policy,
    + STATIC_PRIO(INV_MM_PRIO(param->sched_priority)));
    + else
    + __setscheduler(rq, p, policy, param->sched_priority);

    if (running)
    p->sched_class->set_curr_task(rq);
    @@ -5563,7 +5598,10 @@
    if (retval)
    goto out_unlock;

    - lp.sched_priority = p->rt_priority;
    + if (task_has_mm_policy(p))
    + lp.sched_priority = INV_MM_PRIO(USER_PRIO(p->static_prio));
    + else
    + lp.sched_priority = p->rt_priority;
    read_unlock(&tasklist_lock);

    /*
    @@ -5890,6 +5928,9 @@
    case SCHED_RR:
    ret = MAX_USER_RT_PRIO-1;
    break;
    + case SCHED_MM:
    + ret = MM_PRIO_MAX;
    + break;
    case SCHED_NORMAL:
    case SCHED_BATCH:
    case SCHED_IDLE:
    @@ -5915,10 +5956,14 @@
    case SCHED_RR:
    ret = 1;
    break;
    + case SCHED_MM:
    + ret = MM_PRIO_MIN;
    + break;
    case SCHED_NORMAL:
    case SCHED_BATCH:
    case SCHED_IDLE:
    ret = 0;
    + break;
    }
    return ret;
    }
    \
     
     \ /
      Last update: 2009-05-11 10:35    [W:0.032 / U:63.768 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site