Merge tag 'stable/for-linus-3.8-rc0-bugfix-tag' of git://git.kernel.org/pub/scm/linux...
[firefly-linux-kernel-4.4.55.git] / kernel / pid.c
index 9c219117af362e8199eede8d2ee12dbdcb9c56cc..36aa02ff17d6c9cf67dcf39b0434898c700915ae 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Generic pidhash and scalable, time-bounded PID allocator
  *
- * (C) 2002-2003 William Irwin, IBM
- * (C) 2004 William Irwin, Oracle
+ * (C) 2002-2003 Nadia Yvette Chambers, IBM
+ * (C) 2004 Nadia Yvette Chambers, Oracle
  * (C) 2002-2004 Ingo Molnar, Red Hat
  *
  * pid-structures are backing objects for tasks sharing a given ID to chain
@@ -80,24 +80,10 @@ struct pid_namespace init_pid_ns = {
        .level = 0,
        .child_reaper = &init_task,
        .user_ns = &init_user_ns,
+       .proc_inum = PROC_PID_INIT_INO,
 };
 EXPORT_SYMBOL_GPL(init_pid_ns);
 
-int is_container_init(struct task_struct *tsk)
-{
-       int ret = 0;
-       struct pid *pid;
-
-       rcu_read_lock();
-       pid = task_pid(tsk);
-       if (pid != NULL && pid->numbers[pid->level].nr == 1)
-               ret = 1;
-       rcu_read_unlock();
-
-       return ret;
-}
-EXPORT_SYMBOL(is_container_init);
-
 /*
  * Note: disable interrupts while the pidmap_lock is held as an
  * interrupt might come in and do read_lock(&tasklist_lock).
@@ -273,10 +259,20 @@ void free_pid(struct pid *pid)
        spin_lock_irqsave(&pidmap_lock, flags);
        for (i = 0; i <= pid->level; i++) {
                struct upid *upid = pid->numbers + i;
+               struct pid_namespace *ns = upid->ns;
                hlist_del_rcu(&upid->pid_chain);
-               if (--upid->ns->nr_hashed == 0) {
-                       upid->ns->nr_hashed = -1;
-                       schedule_work(&upid->ns->proc_work);
+               switch(--ns->nr_hashed) {
+               case 1:
+                       /* When all that is left in the pid namespace
+                        * is the reaper wake up the reaper.  The reaper
+                        * may be sleeping in zap_pid_ns_processes().
+                        */
+                       wake_up_process(ns->child_reaper);
+                       break;
+               case 0:
+                       ns->nr_hashed = -1;
+                       schedule_work(&ns->proc_work);
+                       break;
                }
        }
        spin_unlock_irqrestore(&pidmap_lock, flags);