diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/pid.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/kernel/pid.c b/kernel/pid.c index e957f8b09136..9c219117af36 100644 --- a/kernel/pid.c +++ b/kernel/pid.c | |||
@@ -274,8 +274,10 @@ void free_pid(struct pid *pid) | |||
274 | for (i = 0; i <= pid->level; i++) { | 274 | for (i = 0; i <= pid->level; i++) { |
275 | struct upid *upid = pid->numbers + i; | 275 | struct upid *upid = pid->numbers + i; |
276 | hlist_del_rcu(&upid->pid_chain); | 276 | hlist_del_rcu(&upid->pid_chain); |
277 | if (--upid->ns->nr_hashed == 0) | 277 | if (--upid->ns->nr_hashed == 0) { |
278 | upid->ns->nr_hashed = -1; | ||
278 | schedule_work(&upid->ns->proc_work); | 279 | schedule_work(&upid->ns->proc_work); |
280 | } | ||
279 | } | 281 | } |
280 | spin_unlock_irqrestore(&pidmap_lock, flags); | 282 | spin_unlock_irqrestore(&pidmap_lock, flags); |
281 | 283 | ||
@@ -321,6 +323,8 @@ struct pid *alloc_pid(struct pid_namespace *ns) | |||
321 | 323 | ||
322 | upid = pid->numbers + ns->level; | 324 | upid = pid->numbers + ns->level; |
323 | spin_lock_irq(&pidmap_lock); | 325 | spin_lock_irq(&pidmap_lock); |
326 | if (ns->nr_hashed < 0) | ||
327 | goto out_unlock; | ||
324 | for ( ; upid >= pid->numbers; --upid) { | 328 | for ( ; upid >= pid->numbers; --upid) { |
325 | hlist_add_head_rcu(&upid->pid_chain, | 329 | hlist_add_head_rcu(&upid->pid_chain, |
326 | &pid_hash[pid_hashfn(upid->nr, upid->ns)]); | 330 | &pid_hash[pid_hashfn(upid->nr, upid->ns)]); |
@@ -331,6 +335,8 @@ struct pid *alloc_pid(struct pid_namespace *ns) | |||
331 | out: | 335 | out: |
332 | return pid; | 336 | return pid; |
333 | 337 | ||
338 | out_unlock: | ||
339 | spin_unlock(&pidmap_lock); | ||
334 | out_free: | 340 | out_free: |
335 | while (++i <= ns->level) | 341 | while (++i <= ns->level) |
336 | free_pidmap(pid->numbers + i); | 342 | free_pidmap(pid->numbers + i); |