int proc_sched_autogroup_set_nice(struct task_struct *p, int *nice) { static unsigned long next = INITIAL_JIFFIES; struct autogroup *ag; int err; if (*nice < -20 || *nice > 19) return -EINVAL; err = security_task_setnice(current, *nice); if (err) return err; if (*nice < 0 && !can_nice(current, *nice)) return -EPERM; /* this is a heavy operation taking global locks.. */ if (!capable(CAP_SYS_ADMIN) && time_before(jiffies, next)) return -EAGAIN; next = HZ / 10 + jiffies; ag = autogroup_task_get(p); down_write(&ag->lock); err = sched_group_set_shares(ag->tg, prio_to_weight[*nice + 20]); if (!err) ag->nice = *nice; up_write(&ag->lock); autogroup_kref_put(ag); return err; }
static int set_one_prio(struct task_struct *p, int niceval, int error) { int no_nice; if (p->uid != current->euid && p->euid != current->euid && !capable(CAP_SYS_NICE)) { error = -EPERM; goto out; } if (niceval < task_nice(p) && !can_nice(p, niceval)) { error = -EACCES; goto out; } no_nice = security_task_setnice(p, niceval); if (no_nice) { error = no_nice; goto out; } if (error == -ESRCH) error = 0; set_user_nice(p, niceval); out: return error; }