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, |
