--- include/linux/sched.h | 24 +++++++++++-- kernel/sched.c | 90 ++++++++++---------------------------------------- 2 files changed, 38 insertions(+), 76 deletions(-) Index: MM-2.6.17-rc6-mm2/include/linux/sched.h =================================================================== --- MM-2.6.17-rc6-mm2.orig/include/linux/sched.h 2006-06-19 13:57:18.000000000 +1000 +++ MM-2.6.17-rc6-mm2/include/linux/sched.h 2006-06-19 14:28:25.000000000 +1000 @@ -1022,11 +1022,27 @@ struct task_struct { }; #ifdef CONFIG_CPU_RATE_CAPS -unsigned int get_cpu_rate_cap(const struct task_struct *); -int set_cpu_rate_cap(struct task_struct *, unsigned int); +int set_cpu_rate_cap_low(struct task_struct *, unsigned int, int); + +static inline unsigned int get_cpu_rate_cap(const struct task_struct *p) +{ + return p->cpu_rate_cap; +} + +static inline int set_cpu_rate_cap(struct task_struct *p, unsigned int newcap) +{ + return set_cpu_rate_cap_low(p, newcap, 0); +} #ifdef CONFIG_CPU_RATE_HARD_CAPS -unsigned int get_cpu_rate_hard_cap(const struct task_struct *); -int set_cpu_rate_hard_cap(struct task_struct *, unsigned int); +static inline unsigned int get_cpu_rate_hard_cap(const struct task_struct *p) +{ + return p->cpu_rate_hard_cap; +} + +static inline int set_cpu_rate_hard_cap(struct task_struct *p, unsigned int newcap) +{ + return set_cpu_rate_cap_low(p, newcap, 1); +} #endif #endif Index: MM-2.6.17-rc6-mm2/kernel/sched.c =================================================================== --- MM-2.6.17-rc6-mm2.orig/kernel/sched.c 2006-06-19 13:57:18.000000000 +1000 +++ MM-2.6.17-rc6-mm2/kernel/sched.c 2006-06-19 14:28:25.000000000 +1000 @@ -4614,17 +4614,11 @@ out_unlock: } #ifdef CONFIG_CPU_RATE_CAPS -unsigned int get_cpu_rate_cap(const struct task_struct *p) -{ - return p->cpu_rate_cap; -} - -EXPORT_SYMBOL(get_cpu_rate_cap); - /* - * Require: 0 <= new_cap <= CPU_CAP_ONE + * Require: 0 <= new_cap <= CPU_CAP_ONE for hard == 0 + * 1 <= new_cap <= CPU_CAP_ONE otherwise */ -int set_cpu_rate_cap(struct task_struct *p, unsigned int new_cap) +int set_cpu_rate_cap_low(struct task_struct *p, unsigned int new_cap, int hard) { int is_allowed; unsigned long flags; @@ -4634,13 +4628,21 @@ int set_cpu_rate_cap(struct task_struct if (new_cap > CPU_CAP_ONE) return -EINVAL; +#ifdef CONFIG_CPU_RATE_HARD_CAPS + if (hard && new_cap < 1) + return -EINVAL; +#endif is_allowed = capable(CAP_SYS_NICE); /* * We have to be careful, if called from /proc code, * the task might be in the middle of scheduling on another CPU. */ rq = task_rq_lock(p, &flags); +#ifdef CONFIG_CPU_RATE_HARD_CAPS + delta = new_cap - (hard ? p->cpu_rate_hard_cap : p->cpu_rate_cap); +#else delta = new_cap - p->cpu_rate_cap; +#endif if (!is_allowed) { /* * Ordinary users can set/change caps on their own tasks @@ -4656,7 +4658,12 @@ int set_cpu_rate_cap(struct task_struct * set - but as expected it wont have any effect on scheduling until * the task becomes SCHED_NORMAL/SCHED_BATCH: */ - p->cpu_rate_cap = new_cap; +#ifdef CONFIG_CPU_RATE_HARD_CAPS + if (hard) + p->cpu_rate_hard_cap = new_cap; + else +#endif + p->cpu_rate_cap = new_cap; if (has_rt_policy(p)) goto out; @@ -4680,68 +4687,7 @@ out: return 0; } -EXPORT_SYMBOL(set_cpu_rate_cap); - -#ifdef CONFIG_CPU_RATE_HARD_CAPS -unsigned int get_cpu_rate_hard_cap(const struct task_struct *p) -{ - return p->cpu_rate_hard_cap; -} - -EXPORT_SYMBOL(get_cpu_rate_hard_cap); - -/* - * Require: 1 <= new_cap <= CPU_CAP_ONE - */ -int set_cpu_rate_hard_cap(struct task_struct *p, unsigned int new_cap) -{ - int is_allowed; - unsigned long flags; - struct runqueue *rq; - int delta; - - if (new_cap > CPU_CAP_ONE || new_cap < 1) - return -EINVAL; - is_allowed = capable(CAP_SYS_NICE); - /* - * We have to be careful, if called from /proc code, - * the task might be in the middle of scheduling on another CPU. - */ - rq = task_rq_lock(p, &flags); - delta = new_cap - p->cpu_rate_hard_cap; - if (!is_allowed) { - /* - * Ordinary users can set/change caps on their own tasks - * provided that the new setting is MORE constraining - */ - if (((current->euid != p->uid) && (current->uid != p->uid)) || (delta > 0)) { - task_rq_unlock(rq, &flags); - return -EPERM; - } - } - /* - * The RT tasks don't have caps, but we still allow the caps to be - * set - but as expected it wont have any effect on scheduling until - * the task becomes SCHED_NORMAL/SCHED_BATCH: - */ - p->cpu_rate_hard_cap = new_cap; - - if (has_rt_policy(p)) - goto out; - - if (p->array) - dec_raw_weighted_load(rq, p); - set_load_weight(p); - if (p->array) - inc_raw_weighted_load(rq, p); -out: - task_rq_unlock(rq, &flags); - - return 0; -} - -EXPORT_SYMBOL(set_cpu_rate_hard_cap); -#endif +EXPORT_SYMBOL(set_cpu_rate_cap_low); #endif long sched_setaffinity(pid_t pid, cpumask_t new_mask)