move daemonized kernel threads into the swapper's session
[powerpc.git] / kernel / pid.c
index 4b17acd..939746f 100644 (file)
  * allocation scenario when all but one out of 1 million PIDs possible are
  * allocated already: the scanning of 32 list entries and at most PAGE_SIZE
  * bytes. The typical fastpath is a single successful setbit. Freeing is O(1).
+ *
+ * Pid namespaces:
+ *    (C) 2007 Pavel Emelyanov <xemul@openvz.org>, OpenVZ, SWsoft Inc.
+ *    (C) 2007 Sukadev Bhattiprolu <sukadev@us.ibm.com>, IBM
+ *     Many thanks to Oleg Nesterov for comments and help
+ *
  */
 
 #include <linux/mm.h>
@@ -28,6 +34,7 @@
 #include <linux/hash.h>
 #include <linux/pid_namespace.h>
 #include <linux/init_task.h>
+#include <linux/syscalls.h>
 
 #define pid_hashfn(nr, ns)     \
        hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift)
@@ -173,7 +180,7 @@ static int alloc_pidmap(struct pid_namespace *pid_ns)
        return -1;
 }
 
-static int next_pidmap(struct pid_namespace *pid_ns, int last)
+int next_pidmap(struct pid_namespace *pid_ns, int last)
 {
        int offset;
        struct pidmap *map, *end;
@@ -255,7 +262,6 @@ struct pid *alloc_pid(struct pid_namespace *ns)
 
        get_pid_ns(ns);
        pid->level = ns->level;
-       pid->nr = pid->numbers[0].nr;
        atomic_set(&pid->count, 1);
        for (type = 0; type < PIDTYPE_MAX; ++type)
                INIT_HLIST_HEAD(&pid->tasks[type]);
@@ -295,6 +301,18 @@ struct pid * fastcall find_pid_ns(int nr, struct pid_namespace *ns)
 }
 EXPORT_SYMBOL_GPL(find_pid_ns);
 
+struct pid *find_vpid(int nr)
+{
+       return find_pid_ns(nr, current->nsproxy->pid_ns);
+}
+EXPORT_SYMBOL_GPL(find_vpid);
+
+struct pid *find_pid(int nr)
+{
+       return find_pid_ns(nr, &init_pid_ns);
+}
+EXPORT_SYMBOL_GPL(find_pid);
+
 /*
  * attach_pid() must be called with the tasklist_lock write-held.
  */
@@ -349,6 +367,7 @@ struct task_struct * fastcall pid_task(struct pid *pid, enum pid_type type)
        }
        return result;
 }
+EXPORT_SYMBOL(pid_task);
 
 /*
  * Must be called under rcu_read_lock() or with tasklist_lock read-held.
@@ -361,6 +380,25 @@ struct task_struct *find_task_by_pid_type_ns(int type, int nr,
 
 EXPORT_SYMBOL(find_task_by_pid_type_ns);
 
+struct task_struct *find_task_by_pid(pid_t nr)
+{
+       return find_task_by_pid_type_ns(PIDTYPE_PID, nr, &init_pid_ns);
+}
+EXPORT_SYMBOL(find_task_by_pid);
+
+struct task_struct *find_task_by_vpid(pid_t vnr)
+{
+       return find_task_by_pid_type_ns(PIDTYPE_PID, vnr,
+                       current->nsproxy->pid_ns);
+}
+EXPORT_SYMBOL(find_task_by_vpid);
+
+struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns)
+{
+       return find_task_by_pid_type_ns(PIDTYPE_PID, nr, ns);
+}
+EXPORT_SYMBOL(find_task_by_pid_ns);
+
 struct pid *get_task_pid(struct task_struct *task, enum pid_type type)
 {
        struct pid *pid;
@@ -405,6 +443,30 @@ pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns)
        return nr;
 }
 
+pid_t task_pid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
+{
+       return pid_nr_ns(task_pid(tsk), ns);
+}
+EXPORT_SYMBOL(task_pid_nr_ns);
+
+pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
+{
+       return pid_nr_ns(task_tgid(tsk), ns);
+}
+EXPORT_SYMBOL(task_tgid_nr_ns);
+
+pid_t task_pgrp_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
+{
+       return pid_nr_ns(task_pgrp(tsk), ns);
+}
+EXPORT_SYMBOL(task_pgrp_nr_ns);
+
+pid_t task_session_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
+{
+       return pid_nr_ns(task_session(tsk), ns);
+}
+EXPORT_SYMBOL(task_session_nr_ns);
+
 /*
  * Used by proc to find the first pid that is greater then or equal to nr.
  *
@@ -425,71 +487,6 @@ struct pid *find_ge_pid(int nr, struct pid_namespace *ns)
 }
 EXPORT_SYMBOL_GPL(find_get_pid);
 
-struct pid_cache {
-       int nr_ids;
-       char name[16];
-       struct kmem_cache *cachep;
-       struct list_head list;
-};
-
-static LIST_HEAD(pid_caches_lh);
-static DEFINE_MUTEX(pid_caches_mutex);
-
-/*
- * creates the kmem cache to allocate pids from.
- * @nr_ids: the number of numerical ids this pid will have to carry
- */
-
-static struct kmem_cache *create_pid_cachep(int nr_ids)
-{
-       struct pid_cache *pcache;
-       struct kmem_cache *cachep;
-
-       mutex_lock(&pid_caches_mutex);
-       list_for_each_entry (pcache, &pid_caches_lh, list)
-               if (pcache->nr_ids == nr_ids)
-                       goto out;
-
-       pcache = kmalloc(sizeof(struct pid_cache), GFP_KERNEL);
-       if (pcache == NULL)
-               goto err_alloc;
-
-       snprintf(pcache->name, sizeof(pcache->name), "pid_%d", nr_ids);
-       cachep = kmem_cache_create(pcache->name,
-                       /* FIXME add numerical ids here */
-                       sizeof(struct pid), 0, SLAB_HWCACHE_ALIGN, NULL);
-       if (cachep == NULL)
-               goto err_cachep;
-
-       pcache->nr_ids = nr_ids;
-       pcache->cachep = cachep;
-       list_add(&pcache->list, &pid_caches_lh);
-out:
-       mutex_unlock(&pid_caches_mutex);
-       return pcache->cachep;
-
-err_cachep:
-       kfree(pcache);
-err_alloc:
-       mutex_unlock(&pid_caches_mutex);
-       return NULL;
-}
-
-struct pid_namespace *copy_pid_ns(unsigned long flags, struct pid_namespace *old_ns)
-{
-       BUG_ON(!old_ns);
-       get_pid_ns(old_ns);
-       return old_ns;
-}
-
-void free_pid_ns(struct kref *kref)
-{
-       struct pid_namespace *ns;
-
-       ns = container_of(kref, struct pid_namespace, kref);
-       kfree(ns);
-}
-
 /*
  * The pid hash table is scaled according to the amount of memory in the
  * machine.  From a minimum of 16 slots up to 4096 slots at one gigabyte or
@@ -522,7 +519,6 @@ void __init pidmap_init(void)
        set_bit(0, init_pid_ns.pidmap[0].page);
        atomic_dec(&init_pid_ns.pidmap[0].nr_free);
 
-       init_pid_ns.pid_cachep = create_pid_cachep(1);
-       if (init_pid_ns.pid_cachep == NULL)
-               panic("Can't create pid_1 cachep\n");
+       init_pid_ns.pid_cachep = KMEM_CACHE(pid,
+                       SLAB_HWCACHE_ALIGN | SLAB_PANIC);
 }