Commit 2d70b68d42b5196a48ccb639e3797f097ef5bea3
Committed by
Linus Torvalds
1 parent
141d87e7de
Exists in
master
and in
39 other branches
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>
Showing 3 changed files with 17 additions and 8 deletions Side-by-side Diff
fs/ioprio.c
... | ... | @@ -115,11 +115,11 @@ |
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,7 +204,7 @@ |
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,7 +212,7 @@ |
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) |
include/linux/pid.h
... | ... | @@ -161,5 +161,14 @@ |
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 */ |
kernel/sys.c
... | ... | @@ -169,9 +169,9 @@ |
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; |
178 | 178 | |
... | ... | @@ -229,11 +229,11 @@ |
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; |