aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/pid.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/pid.c')
-rw-r--r--kernel/pid.c49
1 files changed, 34 insertions, 15 deletions
diff --git a/kernel/pid.c b/kernel/pid.c
index c7346fb801fc..8132a6ddfa10 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -29,7 +29,8 @@
29#include <linux/pid_namespace.h> 29#include <linux/pid_namespace.h>
30#include <linux/init_task.h> 30#include <linux/init_task.h>
31 31
32#define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift) 32#define pid_hashfn(nr, ns) \
33 hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift)
33static struct hlist_head *pid_hash; 34static struct hlist_head *pid_hash;
34static int pidhash_shift; 35static int pidhash_shift;
35struct pid init_struct_pid = INIT_STRUCT_PID; 36struct pid init_struct_pid = INIT_STRUCT_PID;
@@ -186,11 +187,13 @@ fastcall void put_pid(struct pid *pid)
186 if (!pid) 187 if (!pid)
187 return; 188 return;
188 189
189 /* FIXME - this must be the namespace this pid lives in */ 190 ns = pid->numbers[pid->level].ns;
190 ns = &init_pid_ns;
191 if ((atomic_read(&pid->count) == 1) || 191 if ((atomic_read(&pid->count) == 1) ||
192 atomic_dec_and_test(&pid->count)) 192 atomic_dec_and_test(&pid->count)) {
193 kmem_cache_free(ns->pid_cachep, pid); 193 kmem_cache_free(ns->pid_cachep, pid);
194 if (ns != &init_pid_ns)
195 put_pid_ns(ns);
196 }
194} 197}
195EXPORT_SYMBOL_GPL(put_pid); 198EXPORT_SYMBOL_GPL(put_pid);
196 199
@@ -203,45 +206,61 @@ static void delayed_put_pid(struct rcu_head *rhp)
203fastcall void free_pid(struct pid *pid) 206fastcall void free_pid(struct pid *pid)
204{ 207{
205 /* We can be called with write_lock_irq(&tasklist_lock) held */ 208 /* We can be called with write_lock_irq(&tasklist_lock) held */
209 int i;
206 unsigned long flags; 210 unsigned long flags;
207 211
208 spin_lock_irqsave(&pidmap_lock, flags); 212 spin_lock_irqsave(&pidmap_lock, flags);
209 hlist_del_rcu(&pid->pid_chain); 213 hlist_del_rcu(&pid->pid_chain);
210 spin_unlock_irqrestore(&pidmap_lock, flags); 214 spin_unlock_irqrestore(&pidmap_lock, flags);
211 215
212 free_pidmap(&init_pid_ns, pid->nr); 216 for (i = 0; i <= pid->level; i++)
217 free_pidmap(pid->numbers[i].ns, pid->numbers[i].nr);
218
213 call_rcu(&pid->rcu, delayed_put_pid); 219 call_rcu(&pid->rcu, delayed_put_pid);
214} 220}
215 221
216struct pid *alloc_pid(void) 222struct pid *alloc_pid(struct pid_namespace *ns)
217{ 223{
218 struct pid *pid; 224 struct pid *pid;
219 enum pid_type type; 225 enum pid_type type;
220 int nr = -1; 226 int i, nr;
221 struct pid_namespace *ns; 227 struct pid_namespace *tmp;
222 228
223 ns = task_active_pid_ns(current);
224 pid = kmem_cache_alloc(ns->pid_cachep, GFP_KERNEL); 229 pid = kmem_cache_alloc(ns->pid_cachep, GFP_KERNEL);
225 if (!pid) 230 if (!pid)
226 goto out; 231 goto out;
227 232
228 nr = alloc_pidmap(ns); 233 tmp = ns;
229 if (nr < 0) 234 for (i = ns->level; i >= 0; i--) {
230 goto out_free; 235 nr = alloc_pidmap(tmp);
236 if (nr < 0)
237 goto out_free;
231 238
239 pid->numbers[i].nr = nr;
240 pid->numbers[i].ns = tmp;
241 tmp = tmp->parent;
242 }
243
244 if (ns != &init_pid_ns)
245 get_pid_ns(ns);
246
247 pid->level = ns->level;
248 pid->nr = pid->numbers[0].nr;
232 atomic_set(&pid->count, 1); 249 atomic_set(&pid->count, 1);
233 pid->nr = nr;
234 for (type = 0; type < PIDTYPE_MAX; ++type) 250 for (type = 0; type < PIDTYPE_MAX; ++type)
235 INIT_HLIST_HEAD(&pid->tasks[type]); 251 INIT_HLIST_HEAD(&pid->tasks[type]);
236 252
237 spin_lock_irq(&pidmap_lock); 253 spin_lock_irq(&pidmap_lock);
238 hlist_add_head_rcu(&pid->pid_chain, &pid_hash[pid_hashfn(pid->nr)]); 254 hlist_add_head_rcu(&pid->pid_chain, &pid_hash[pid_hashfn(pid->nr, ns)]);
239 spin_unlock_irq(&pidmap_lock); 255 spin_unlock_irq(&pidmap_lock);
240 256
241out: 257out:
242 return pid; 258 return pid;
243 259
244out_free: 260out_free:
261 for (i++; i <= ns->level; i++)
262 free_pidmap(pid->numbers[i].ns, pid->numbers[i].nr);
263
245 kmem_cache_free(ns->pid_cachep, pid); 264 kmem_cache_free(ns->pid_cachep, pid);
246 pid = NULL; 265 pid = NULL;
247 goto out; 266 goto out;
@@ -253,7 +272,7 @@ struct pid * fastcall find_pid(int nr)
253 struct pid *pid; 272 struct pid *pid;
254 273
255 hlist_for_each_entry_rcu(pid, elem, 274 hlist_for_each_entry_rcu(pid, elem,
256 &pid_hash[pid_hashfn(nr)], pid_chain) { 275 &pid_hash[pid_hashfn(nr, &init_pid_ns)], pid_chain) {
257 if (pid->nr == nr) 276 if (pid->nr == nr)
258 return pid; 277 return pid;
259 } 278 }