Messages in this thread | | | Date | Wed, 10 Sep 2008 13:57:09 +0200 | From | "Michael Kerrisk" <> | Subject | Re: [PATCH] make setpriority POSIX compliant; introduce PRIO_THREAD extension |
| |
Denys,
On 9/10/08, Denys Vlasenko <dvlasenk@redhat.com> wrote: > On Tue, 2008-09-09 at 17:45 +0200, Michael Kerrisk wrote: > > > Patch is run tested. I will post test program etc as a reply. > > > > Tested-by: Michael Kerrisk <mtk.manpages@gmail.com> > > > > Please do CC me on API changes, so that they might get documented in > > the man pages. > > > > Thanks for this work. (I'm not sure whether or not it's a response to > > my bug report, http://bugzilla.kernel.org/show_bug.cgi?id=6258 ) > > I worked on it because of this bug report: > > https://bugzilla.redhat.com/show_bug.cgi?id=455251
(That report is inaccessible, although I have some kind of bugzilla login there: "You are not authorized to access bug #455251.")
> > I tested your patch. Most things seem to work as I would expect, but > > there is one strangeness. > > > > I would expect > > setpriority(PRIO_PROCESS, getpid()) > > and > > setpriority(PRIO_PROCESS, 0) > > to have the same affect (because: which == PRIO_PRCESS, who == 0 > > conventionally means "the calling process"). > > > > But they do not: the latter call only changes the priority of the > > calling thread. Is this intended? > > No, it was not intended. I think this error is here: > > + case PRIO_PROCESS: > + if (who) > + pid = find_vpid(who); > + else { > + pid = task_pid(current); > + who = current->pid; > + } > > I was confused. ->pid is TID, had to use ->tgid to get PID.
(Indeed as I read Chris Freiesen's mail I almost tripped up with the same confusion. The source code names of these fields can easily lead to confusions like that.)
> The fix: replace > who = current->pid; > with > who = current->tgid; > There are two places where you need to do it. > > Updated patch is below.
Tested-by: Michael Kerrisk <mtk.manpages@gmail.com>
With your suggested change, things now work as I would expect. Thanks!
Cheers,
Michael
> Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com> > -- > vda > > > > diff --git a/include/linux/resource.h b/include/linux/resource.h > index aaa423a..f292690 100644 > --- a/include/linux/resource.h > +++ b/include/linux/resource.h > @@ -51,6 +51,7 @@ struct rlimit { > #define PRIO_PROCESS 0 > #define PRIO_PGRP 1 > #define PRIO_USER 2 > +#define PRIO_THREAD 3 > > /* > * Limit the stack by to some sane default: root can always > diff --git a/kernel/sys.c b/kernel/sys.c > index 038a7bc..d339c1a 100644 > --- a/kernel/sys.c > +++ b/kernel/sys.c > @@ -142,9 +142,9 @@ asmlinkage long sys_setpriority(int which, int who, > int niceval) > struct task_struct *g, *p; > struct user_struct *user; > int error = -EINVAL; > - struct pid *pgrp; > + struct pid *pgrp, *pid; > > - if (which > PRIO_USER || which < PRIO_PROCESS) > + if (which > PRIO_THREAD || which < PRIO_PROCESS) > goto out; > > /* normalize: avoid signed division (rounding problems) */ > @@ -156,7 +156,7 @@ asmlinkage long sys_setpriority(int which, int who, > int niceval) > > read_lock(&tasklist_lock); > switch (which) { > - case PRIO_PROCESS: > + case PRIO_THREAD: > if (who) > p = find_task_by_vpid(who); > else > @@ -164,6 +164,19 @@ asmlinkage long sys_setpriority(int which, int who, > int niceval) > if (p) > error = set_one_prio(p, niceval, error); > break; > + case PRIO_PROCESS: > + if (who) > + pid = find_vpid(who); > + else { > + pid = task_pid(current); > + who = current->tgid; > + } > + do_each_pid_thread(pid, PIDTYPE_PID, p) { > + if (who == p->pid || who == p->tgid) { > + error = set_one_prio(p, niceval, error); > + } > + } while_each_pid_thread(pid, PIDTYPE_PID, p); > + break; > case PRIO_PGRP: > if (who) > pgrp = find_vpid(who); > @@ -206,14 +219,14 @@ asmlinkage long sys_getpriority(int which, int > who) > struct task_struct *g, *p; > struct user_struct *user; > long niceval, retval = -ESRCH; > - struct pid *pgrp; > + struct pid *pgrp, *pid; > > - if (which > PRIO_USER || which < PRIO_PROCESS) > + if (which > PRIO_THREAD || which < PRIO_PROCESS) > return -EINVAL; > > read_lock(&tasklist_lock); > switch (which) { > - case PRIO_PROCESS: > + case PRIO_THREAD: > if (who) > p = find_task_by_vpid(who); > else > @@ -224,6 +237,21 @@ asmlinkage long sys_getpriority(int which, int who) > retval = niceval; > } > break; > + case PRIO_PROCESS: > + if (who) > + pid = find_vpid(who); > + else { > + pid = task_pid(current); > + who = current->tgid; > + } > + do_each_pid_thread(pid, PIDTYPE_PID, p) { > + if (who == p->pid || who == p->tgid) { > + niceval = 20 - task_nice(p); > + if (niceval > retval) > + retval = niceval; > + } > + } while_each_pid_thread(pid, PIDTYPE_PID, p); > + break; > case PRIO_PGRP: > if (who) > pgrp = find_vpid(who); > > > >
-- Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ man-pages online: http://www.kernel.org/doc/man-pages/online_pages.html Found a bug? http://www.kernel.org/doc/man-pages/reporting_bugs.html
| |