diff options
Diffstat (limited to 'kernel/pid.c')
-rw-r--r-- | kernel/pid.c | 41 |
1 files changed, 23 insertions, 18 deletions
diff --git a/kernel/pid.c b/kernel/pid.c index 477691576b33..20d59fa2d493 100644 --- a/kernel/pid.c +++ b/kernel/pid.c | |||
@@ -111,10 +111,11 @@ EXPORT_SYMBOL(is_container_init); | |||
111 | 111 | ||
112 | static __cacheline_aligned_in_smp DEFINE_SPINLOCK(pidmap_lock); | 112 | static __cacheline_aligned_in_smp DEFINE_SPINLOCK(pidmap_lock); |
113 | 113 | ||
114 | static void free_pidmap(struct pid_namespace *pid_ns, int pid) | 114 | static void free_pidmap(struct upid *upid) |
115 | { | 115 | { |
116 | struct pidmap *map = pid_ns->pidmap + pid / BITS_PER_PAGE; | 116 | int nr = upid->nr; |
117 | int offset = pid & BITS_PER_PAGE_MASK; | 117 | struct pidmap *map = upid->ns->pidmap + nr / BITS_PER_PAGE; |
118 | int offset = nr & BITS_PER_PAGE_MASK; | ||
118 | 119 | ||
119 | clear_bit(offset, map->page); | 120 | clear_bit(offset, map->page); |
120 | atomic_inc(&map->nr_free); | 121 | atomic_inc(&map->nr_free); |
@@ -232,7 +233,7 @@ void free_pid(struct pid *pid) | |||
232 | spin_unlock_irqrestore(&pidmap_lock, flags); | 233 | spin_unlock_irqrestore(&pidmap_lock, flags); |
233 | 234 | ||
234 | for (i = 0; i <= pid->level; i++) | 235 | for (i = 0; i <= pid->level; i++) |
235 | free_pidmap(pid->numbers[i].ns, pid->numbers[i].nr); | 236 | free_pidmap(pid->numbers + i); |
236 | 237 | ||
237 | call_rcu(&pid->rcu, delayed_put_pid); | 238 | call_rcu(&pid->rcu, delayed_put_pid); |
238 | } | 239 | } |
@@ -278,8 +279,8 @@ out: | |||
278 | return pid; | 279 | return pid; |
279 | 280 | ||
280 | out_free: | 281 | out_free: |
281 | for (i++; i <= ns->level; i++) | 282 | while (++i <= ns->level) |
282 | free_pidmap(pid->numbers[i].ns, pid->numbers[i].nr); | 283 | free_pidmap(pid->numbers + i); |
283 | 284 | ||
284 | kmem_cache_free(ns->pid_cachep, pid); | 285 | kmem_cache_free(ns->pid_cachep, pid); |
285 | pid = NULL; | 286 | pid = NULL; |
@@ -316,7 +317,7 @@ EXPORT_SYMBOL_GPL(find_pid); | |||
316 | /* | 317 | /* |
317 | * attach_pid() must be called with the tasklist_lock write-held. | 318 | * attach_pid() must be called with the tasklist_lock write-held. |
318 | */ | 319 | */ |
319 | int attach_pid(struct task_struct *task, enum pid_type type, | 320 | void attach_pid(struct task_struct *task, enum pid_type type, |
320 | struct pid *pid) | 321 | struct pid *pid) |
321 | { | 322 | { |
322 | struct pid_link *link; | 323 | struct pid_link *link; |
@@ -324,11 +325,10 @@ int attach_pid(struct task_struct *task, enum pid_type type, | |||
324 | link = &task->pids[type]; | 325 | link = &task->pids[type]; |
325 | link->pid = pid; | 326 | link->pid = pid; |
326 | hlist_add_head_rcu(&link->node, &pid->tasks[type]); | 327 | hlist_add_head_rcu(&link->node, &pid->tasks[type]); |
327 | |||
328 | return 0; | ||
329 | } | 328 | } |
330 | 329 | ||
331 | void detach_pid(struct task_struct *task, enum pid_type type) | 330 | static void __change_pid(struct task_struct *task, enum pid_type type, |
331 | struct pid *new) | ||
332 | { | 332 | { |
333 | struct pid_link *link; | 333 | struct pid_link *link; |
334 | struct pid *pid; | 334 | struct pid *pid; |
@@ -338,7 +338,7 @@ void detach_pid(struct task_struct *task, enum pid_type type) | |||
338 | pid = link->pid; | 338 | pid = link->pid; |
339 | 339 | ||
340 | hlist_del_rcu(&link->node); | 340 | hlist_del_rcu(&link->node); |
341 | link->pid = NULL; | 341 | link->pid = new; |
342 | 342 | ||
343 | for (tmp = PIDTYPE_MAX; --tmp >= 0; ) | 343 | for (tmp = PIDTYPE_MAX; --tmp >= 0; ) |
344 | if (!hlist_empty(&pid->tasks[tmp])) | 344 | if (!hlist_empty(&pid->tasks[tmp])) |
@@ -347,13 +347,24 @@ void detach_pid(struct task_struct *task, enum pid_type type) | |||
347 | free_pid(pid); | 347 | free_pid(pid); |
348 | } | 348 | } |
349 | 349 | ||
350 | void detach_pid(struct task_struct *task, enum pid_type type) | ||
351 | { | ||
352 | __change_pid(task, type, NULL); | ||
353 | } | ||
354 | |||
355 | void change_pid(struct task_struct *task, enum pid_type type, | ||
356 | struct pid *pid) | ||
357 | { | ||
358 | __change_pid(task, type, pid); | ||
359 | attach_pid(task, type, pid); | ||
360 | } | ||
361 | |||
350 | /* transfer_pid is an optimization of attach_pid(new), detach_pid(old) */ | 362 | /* transfer_pid is an optimization of attach_pid(new), detach_pid(old) */ |
351 | void transfer_pid(struct task_struct *old, struct task_struct *new, | 363 | void transfer_pid(struct task_struct *old, struct task_struct *new, |
352 | enum pid_type type) | 364 | enum pid_type type) |
353 | { | 365 | { |
354 | new->pids[type].pid = old->pids[type].pid; | 366 | new->pids[type].pid = old->pids[type].pid; |
355 | hlist_replace_rcu(&old->pids[type].node, &new->pids[type].node); | 367 | hlist_replace_rcu(&old->pids[type].node, &new->pids[type].node); |
356 | old->pids[type].pid = NULL; | ||
357 | } | 368 | } |
358 | 369 | ||
359 | struct task_struct *pid_task(struct pid *pid, enum pid_type type) | 370 | struct task_struct *pid_task(struct pid *pid, enum pid_type type) |
@@ -380,12 +391,6 @@ struct task_struct *find_task_by_pid_type_ns(int type, int nr, | |||
380 | 391 | ||
381 | EXPORT_SYMBOL(find_task_by_pid_type_ns); | 392 | EXPORT_SYMBOL(find_task_by_pid_type_ns); |
382 | 393 | ||
383 | struct task_struct *find_task_by_pid(pid_t nr) | ||
384 | { | ||
385 | return find_task_by_pid_type_ns(PIDTYPE_PID, nr, &init_pid_ns); | ||
386 | } | ||
387 | EXPORT_SYMBOL(find_task_by_pid); | ||
388 | |||
389 | struct task_struct *find_task_by_vpid(pid_t vnr) | 394 | struct task_struct *find_task_by_vpid(pid_t vnr) |
390 | { | 395 | { |
391 | return find_task_by_pid_type_ns(PIDTYPE_PID, vnr, | 396 | return find_task_by_pid_type_ns(PIDTYPE_PID, vnr, |