Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fix setpriority(PRIO_PGRP) thread iterator breakage

When user calls sys_setpriority(PRIO_PGRP ...) on a NPTL style multi-LWP
process, only the task leader of the process is affected, all other
sibling LWP threads didn't receive the setting. The problem was that the
iterator used in sys_setpriority() only iteartes over one task for each
process, ignoring all other sibling thread.

Introduce a new macro do_each_pid_thread / while_each_pid_thread to walk
each thread of a process. Convert 4 call sites in {set/get}priority and
ioprio_{set/get}.

Signed-off-by: Ken Chen <kenchen@google.com>
Cc: Oleg Nesterov <oleg@tv-sign.ru>
Cc: Roland McGrath <roland@redhat.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Jens Axboe <jens.axboe@oracle.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Ken Chen and committed by
Linus Torvalds
2d70b68d 141d87e7

+17 -8
+4 -4
fs/ioprio.c
··· 115 115 pgrp = task_pgrp(current); 116 116 else 117 117 pgrp = find_vpid(who); 118 - do_each_pid_task(pgrp, PIDTYPE_PGID, p) { 118 + do_each_pid_thread(pgrp, PIDTYPE_PGID, p) { 119 119 ret = set_task_ioprio(p, ioprio); 120 120 if (ret) 121 121 break; 122 - } while_each_pid_task(pgrp, PIDTYPE_PGID, p); 122 + } while_each_pid_thread(pgrp, PIDTYPE_PGID, p); 123 123 break; 124 124 case IOPRIO_WHO_USER: 125 125 if (!who) ··· 204 204 pgrp = task_pgrp(current); 205 205 else 206 206 pgrp = find_vpid(who); 207 - do_each_pid_task(pgrp, PIDTYPE_PGID, p) { 207 + do_each_pid_thread(pgrp, PIDTYPE_PGID, p) { 208 208 tmpio = get_task_ioprio(p); 209 209 if (tmpio < 0) 210 210 continue; ··· 212 212 ret = tmpio; 213 213 else 214 214 ret = ioprio_best(ret, tmpio); 215 - } while_each_pid_task(pgrp, PIDTYPE_PGID, p); 215 + } while_each_pid_thread(pgrp, PIDTYPE_PGID, p); 216 216 break; 217 217 case IOPRIO_WHO_USER: 218 218 if (!who)
+9
include/linux/pid.h
··· 161 161 } \ 162 162 } while (0) 163 163 164 + #define do_each_pid_thread(pid, type, task) \ 165 + do_each_pid_task(pid, type, task) { \ 166 + struct task_struct *tg___ = task; \ 167 + do { 168 + 169 + #define while_each_pid_thread(pid, type, task) \ 170 + } while_each_thread(tg___, task); \ 171 + task = tg___; \ 172 + } while_each_pid_task(pid, type, task) 164 173 #endif /* _LINUX_PID_H */
+4 -4
kernel/sys.c
··· 169 169 pgrp = find_vpid(who); 170 170 else 171 171 pgrp = task_pgrp(current); 172 - do_each_pid_task(pgrp, PIDTYPE_PGID, p) { 172 + do_each_pid_thread(pgrp, PIDTYPE_PGID, p) { 173 173 error = set_one_prio(p, niceval, error); 174 - } while_each_pid_task(pgrp, PIDTYPE_PGID, p); 174 + } while_each_pid_thread(pgrp, PIDTYPE_PGID, p); 175 175 break; 176 176 case PRIO_USER: 177 177 user = current->user; ··· 229 229 pgrp = find_vpid(who); 230 230 else 231 231 pgrp = task_pgrp(current); 232 - do_each_pid_task(pgrp, PIDTYPE_PGID, p) { 232 + do_each_pid_thread(pgrp, PIDTYPE_PGID, p) { 233 233 niceval = 20 - task_nice(p); 234 234 if (niceval > retval) 235 235 retval = niceval; 236 - } while_each_pid_task(pgrp, PIDTYPE_PGID, p); 236 + } while_each_pid_thread(pgrp, PIDTYPE_PGID, p); 237 237 break; 238 238 case PRIO_USER: 239 239 user = current->user;