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 @@ -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; }