diff options
Diffstat (limited to 'kernel/pid.c')
-rw-r--r-- | kernel/pid.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/kernel/pid.c b/kernel/pid.c index d3f722d20f9c..aebb30d9c233 100644 --- a/kernel/pid.c +++ b/kernel/pid.c | |||
@@ -141,11 +141,12 @@ static int alloc_pidmap(struct pid_namespace *pid_ns) | |||
141 | * installing it: | 141 | * installing it: |
142 | */ | 142 | */ |
143 | spin_lock_irq(&pidmap_lock); | 143 | spin_lock_irq(&pidmap_lock); |
144 | if (map->page) | 144 | if (!map->page) { |
145 | kfree(page); | ||
146 | else | ||
147 | map->page = page; | 145 | map->page = page; |
146 | page = NULL; | ||
147 | } | ||
148 | spin_unlock_irq(&pidmap_lock); | 148 | spin_unlock_irq(&pidmap_lock); |
149 | kfree(page); | ||
149 | if (unlikely(!map->page)) | 150 | if (unlikely(!map->page)) |
150 | break; | 151 | break; |
151 | } | 152 | } |
@@ -268,12 +269,11 @@ struct pid *alloc_pid(struct pid_namespace *ns) | |||
268 | for (type = 0; type < PIDTYPE_MAX; ++type) | 269 | for (type = 0; type < PIDTYPE_MAX; ++type) |
269 | INIT_HLIST_HEAD(&pid->tasks[type]); | 270 | INIT_HLIST_HEAD(&pid->tasks[type]); |
270 | 271 | ||
272 | upid = pid->numbers + ns->level; | ||
271 | spin_lock_irq(&pidmap_lock); | 273 | spin_lock_irq(&pidmap_lock); |
272 | for (i = ns->level; i >= 0; i--) { | 274 | for ( ; upid >= pid->numbers; --upid) |
273 | upid = &pid->numbers[i]; | ||
274 | hlist_add_head_rcu(&upid->pid_chain, | 275 | hlist_add_head_rcu(&upid->pid_chain, |
275 | &pid_hash[pid_hashfn(upid->nr, upid->ns)]); | 276 | &pid_hash[pid_hashfn(upid->nr, upid->ns)]); |
276 | } | ||
277 | spin_unlock_irq(&pidmap_lock); | 277 | spin_unlock_irq(&pidmap_lock); |
278 | 278 | ||
279 | out: | 279 | out: |
@@ -367,7 +367,9 @@ struct task_struct *pid_task(struct pid *pid, enum pid_type type) | |||
367 | struct task_struct *result = NULL; | 367 | struct task_struct *result = NULL; |
368 | if (pid) { | 368 | if (pid) { |
369 | struct hlist_node *first; | 369 | struct hlist_node *first; |
370 | first = rcu_dereference(pid->tasks[type].first); | 370 | first = rcu_dereference_check(pid->tasks[type].first, |
371 | rcu_read_lock_held() || | ||
372 | lockdep_tasklist_lock_is_held()); | ||
371 | if (first) | 373 | if (first) |
372 | result = hlist_entry(first, struct task_struct, pids[(type)].node); | 374 | result = hlist_entry(first, struct task_struct, pids[(type)].node); |
373 | } | 375 | } |
@@ -376,7 +378,7 @@ struct task_struct *pid_task(struct pid *pid, enum pid_type type) | |||
376 | EXPORT_SYMBOL(pid_task); | 378 | EXPORT_SYMBOL(pid_task); |
377 | 379 | ||
378 | /* | 380 | /* |
379 | * Must be called under rcu_read_lock() or with tasklist_lock read-held. | 381 | * Must be called under rcu_read_lock(). |
380 | */ | 382 | */ |
381 | struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns) | 383 | struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns) |
382 | { | 384 | { |