[Devel] [PATCH 20/28] [FLAT 5/6] Flat model pid manipulations
Pavel Emelianov
xemul at openvz.org
Fri Jun 15 09:20:19 PDT 2007
The alloc_pid(), free_pid() and put_pid() implementation for flat
model (see [PREP 10/14]). This model allocates ids from two maps and
hashes the pid in two tables.
Signed-off-by: Pavel Emelianov <xemul at openvz.org>
---
pid.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 99 insertions(+)
--- ./kernel/pid.c.flatcore 2007-06-15 15:14:33.000000000 +0400
+++ ./kernel/pid.c 2007-06-15 15:26:23.000000000 +0400
@@ -64,6 +64,12 @@ static inline int mk_pid(struct pid_name
static struct hlist_head *pid_hash2;
#define pid_ehashfn(nr, ns) hash_long((unsigned long)nr + (unsigned long)ns, \
pidhash_shift)
+
+#ifdef CONFIG_PID_NS_FLAT
+/* flat model uses the second hash to find the pids by their virtual nrs */
+#define vpid_hash pid_hash2
+#define vpid_hashfn pid_ehashfn
+#endif
#endif
/*
@@ -233,6 +239,99 @@ struct pid * fastcall find_pid_ns(int nr
return NULL;
}
#else
+#ifdef CONFIG_PID_NS_FLAT
+static inline int alloc_pid_nrs(struct pid *pid)
+{
+ int nr, vnr;
+ struct pid_namespace *ns;
+
+ vnr = nr = alloc_pidmap(&init_pid_ns);
+ if (nr < 0)
+ goto out;
+
+ ns = current->nsproxy->pid_ns;
+ /*
+ * pids in init namespace have both nr and vnr equal
+ * pids in subnamespace hold the namespace
+ */
+ if (ns != &init_pid_ns) {
+ vnr = alloc_pidmap(ns);
+ if (vnr < 0)
+ goto out_vnr;
+
+ get_pid_ns(ns);
+ }
+
+ pid->nr = nr;
+ pid->vnr = vnr;
+ pid->ns = ns;
+ spin_lock_irq(&pidmap_lock);
+ hlist_add_head_rcu(&pid->pid_chain, &pid_hash[pid_hashfn(nr)]);
+ if (ns != &init_pid_ns)
+ hlist_add_head_rcu(&pid->vpid_chain,
+ &vpid_hash[vpid_hashfn(vnr, ns)]);
+ spin_unlock_irq(&pidmap_lock);
+ return 0;
+
+out_vnr:
+ free_pidmap(&init_pid_ns, nr);
+out:
+ return vnr;
+}
+
+static inline void unhash_pid_nrs(struct pid *pid)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&pidmap_lock, flags);
+ hlist_del_rcu(&pid->pid_chain);
+ if (pid->ns != &init_pid_ns)
+ hlist_del_rcu(&pid->vpid_chain);
+ spin_unlock_irqrestore(&pidmap_lock, flags);
+
+ free_pidmap(&init_pid_ns, pid->nr);
+ if (pid->ns != &init_pid_ns)
+ free_pidmap(pid->ns, pid->vnr);
+}
+
+static inline void free_pid_nrs(struct pid *pid)
+{
+ if (pid->ns != &init_pid_ns)
+ put_pid_ns(pid->ns);
+}
+
+static inline struct pid *find_global_pid(int nr)
+{
+ struct pid *pid;
+ struct hlist_node *elem;
+
+ hlist_for_each_entry_rcu(pid, elem,
+ &pid_hash[pid_hashfn(nr)], pid_chain) {
+ if (pid->nr == nr)
+ return pid;
+ }
+ return NULL;
+}
+
+static inline struct pid *find_virtual_pid(int nr, struct pid_namespace *ns)
+{
+ struct pid *pid;
+ struct hlist_node *elem;
+
+ hlist_for_each_entry_rcu(pid, elem,
+ &vpid_hash[vpid_hashfn(nr, ns)], vpid_chain) {
+ if (pid->vnr == nr && pid->ns == ns)
+ return pid;
+ }
+ return NULL;
+}
+
+struct pid * fastcall find_pid_ns(int nr, struct pid_namespace *ns)
+{
+ return (ns == &init_pid_ns ?
+ find_global_pid(nr) : find_virtual_pid(nr, ns));
+}
+#endif
#endif
EXPORT_SYMBOL_GPL(find_pid_ns);
_______________________________________________
Containers mailing list
Containers at lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/containers
More information about the Devel
mailing list