Blame view

kernel/pid.c 12.9 KB
457c89965   Thomas Gleixner   treewide: Add SPD...
1
  // SPDX-License-Identifier: GPL-2.0-only
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
  /*
   * Generic pidhash and scalable, time-bounded PID allocator
   *
6d49e352a   Nadia Yvette Chambers   propagate name ch...
5
6
   * (C) 2002-2003 Nadia Yvette Chambers, IBM
   * (C) 2004 Nadia Yvette Chambers, Oracle
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
   * (C) 2002-2004 Ingo Molnar, Red Hat
   *
   * pid-structures are backing objects for tasks sharing a given ID to chain
   * against. There is very little to them aside from hashing them and
   * parking tasks using given ID's on a list.
   *
   * The hash is always changed with the tasklist_lock write-acquired,
   * and the hash is only accessed with the tasklist_lock at least
   * read-acquired, so there's no additional SMP locking needed here.
   *
   * We have a list of bitmap pages, which bitmaps represent the PID space.
   * Allocating and freeing PIDs is completely lockless. The worst-case
   * 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).
30e49c263   Pavel Emelyanov   pid namespaces: a...
22
23
24
25
26
27
   *
   * 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
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
28
29
30
   */
  
  #include <linux/mm.h>
9984de1a5   Paul Gortmaker   kernel: Map most ...
31
  #include <linux/export.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
32
33
  #include <linux/slab.h>
  #include <linux/init.h>
82524746c   Franck Bui-Huu   rcu: split list.h...
34
  #include <linux/rculist.h>
57c8a661d   Mike Rapoport   mm: remove includ...
35
  #include <linux/memblock.h>
61a58c6c2   Sukadev Bhattiprolu   [PATCH] rename st...
36
  #include <linux/pid_namespace.h>
820e45db2   Sukadev Bhattiprolu   statically initia...
37
  #include <linux/init_task.h>
3eb07c8c8   Sukadev Bhattiprolu   pid namespaces: d...
38
  #include <linux/syscalls.h>
0bb80f240   David Howells   proc: Split the n...
39
  #include <linux/proc_ns.h>
f57e515a1   Joel Fernandes (Google)   kernel/pid.c: con...
40
  #include <linux/refcount.h>
32fcb426e   Christian Brauner   pid: add pidfd_op...
41
42
  #include <linux/anon_inodes.h>
  #include <linux/sched/signal.h>
299300258   Ingo Molnar   sched/headers: Pr...
43
  #include <linux/sched/task.h>
95846ecf9   Gargi Sharma   pid: replace pid ...
44
  #include <linux/idr.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
45

e1e871aff   David Howells   Expand INIT_STRUC...
46
  struct pid init_struct_pid = {
f57e515a1   Joel Fernandes (Google)   kernel/pid.c: con...
47
  	.count		= REFCOUNT_INIT(1),
e1e871aff   David Howells   Expand INIT_STRUC...
48
49
50
51
52
53
54
55
56
57
58
  	.tasks		= {
  		{ .first = NULL },
  		{ .first = NULL },
  		{ .first = NULL },
  	},
  	.level		= 0,
  	.numbers	= { {
  		.nr		= 0,
  		.ns		= &init_pid_ns,
  	}, }
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
60
  
  int pid_max = PID_MAX_DEFAULT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
62
63
64
65
  
  #define RESERVED_PIDS		300
  
  int pid_max_min = RESERVED_PIDS + 1;
  int pid_max_max = PID_MAX_LIMIT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
66
67
68
69
70
71
  /*
   * PID-map pages start out as NULL, they get allocated upon
   * first use and are never deallocated. This way a low pid_max
   * value does not cause lots of bitmaps to be allocated, but
   * the scheme scales to up to 4 million PIDs, runtime.
   */
61a58c6c2   Sukadev Bhattiprolu   [PATCH] rename st...
72
  struct pid_namespace init_pid_ns = {
1e24edca0   Peter Zijlstra   locking/atomic, k...
73
  	.kref = KREF_INIT(2),
f6bb2a2c0   Matthew Wilcox   xarray: add the x...
74
  	.idr = IDR_INIT(init_pid_ns.idr),
e8cfbc245   Gargi Sharma   pid: remove pidhash
75
  	.pid_allocated = PIDNS_ADDING,
faacbfd3a   Pavel Emelyanov   pid namespaces: a...
76
77
  	.level = 0,
  	.child_reaper = &init_task,
49f4d8b93   Eric W. Biederman   pidns: Capture th...
78
  	.user_ns = &init_user_ns,
435d5f4bb   Al Viro   common object emb...
79
  	.ns.inum = PROC_PID_INIT_INO,
33c429405   Al Viro   copy address of p...
80
81
82
  #ifdef CONFIG_PID_NS
  	.ns.ops = &pidns_operations,
  #endif
3fbc96486   Sukadev Bhattiprolu   [PATCH] Define st...
83
  };
198fe21b0   Pavel Emelyanov   pid namespaces: h...
84
  EXPORT_SYMBOL_GPL(init_pid_ns);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
85

92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
86
87
88
89
90
91
92
93
94
95
96
97
98
  /*
   * Note: disable interrupts while the pidmap_lock is held as an
   * interrupt might come in and do read_lock(&tasklist_lock).
   *
   * If we don't disable interrupts there is a nasty deadlock between
   * detach_pid()->free_pid() and another cpu that does
   * spin_lock(&pidmap_lock) followed by an interrupt routine that does
   * read_lock(&tasklist_lock);
   *
   * After we clean up the tasklist_lock and know there are no
   * irq handlers that take it we can leave the interrupts enabled.
   * For now it is easier to be safe than to prove it can't happen.
   */
3fbc96486   Sukadev Bhattiprolu   [PATCH] Define st...
99

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
100
  static  __cacheline_aligned_in_smp DEFINE_SPINLOCK(pidmap_lock);
7ad5b3a50   Harvey Harrison   kernel: remove fa...
101
  void put_pid(struct pid *pid)
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
102
  {
baf8f0f82   Pavel Emelianov   pid namespaces: d...
103
  	struct pid_namespace *ns;
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
104
105
  	if (!pid)
  		return;
baf8f0f82   Pavel Emelianov   pid namespaces: d...
106

8ef047aaa   Pavel Emelyanov   pid namespaces: m...
107
  	ns = pid->numbers[pid->level].ns;
f57e515a1   Joel Fernandes (Google)   kernel/pid.c: con...
108
  	if (refcount_dec_and_test(&pid->count)) {
baf8f0f82   Pavel Emelianov   pid namespaces: d...
109
  		kmem_cache_free(ns->pid_cachep, pid);
b461cc038   Pavel Emelyanov   pid namespaces: m...
110
  		put_pid_ns(ns);
8ef047aaa   Pavel Emelyanov   pid namespaces: m...
111
  	}
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
112
  }
bbf73147e   Eric W. Biederman   [PATCH] pid: expo...
113
  EXPORT_SYMBOL_GPL(put_pid);
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
114
115
116
117
118
119
  
  static void delayed_put_pid(struct rcu_head *rhp)
  {
  	struct pid *pid = container_of(rhp, struct pid, rcu);
  	put_pid(pid);
  }
7ad5b3a50   Harvey Harrison   kernel: remove fa...
120
  void free_pid(struct pid *pid)
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
121
122
  {
  	/* We can be called with write_lock_irq(&tasklist_lock) held */
8ef047aaa   Pavel Emelyanov   pid namespaces: m...
123
  	int i;
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
124
125
126
  	unsigned long flags;
  
  	spin_lock_irqsave(&pidmap_lock, flags);
0a01f2cc3   Eric W. Biederman   pidns: Make the p...
127
128
  	for (i = 0; i <= pid->level; i++) {
  		struct upid *upid = pid->numbers + i;
af4b8a83a   Eric W. Biederman   pidns: Wait in za...
129
  		struct pid_namespace *ns = upid->ns;
e8cfbc245   Gargi Sharma   pid: remove pidhash
130
  		switch (--ns->pid_allocated) {
a60648851   Eric W. Biederman   pidns: Fix hang i...
131
  		case 2:
af4b8a83a   Eric W. Biederman   pidns: Wait in za...
132
133
134
135
136
137
138
  		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;
e8cfbc245   Gargi Sharma   pid: remove pidhash
139
  		case PIDNS_ADDING:
314a8ad0f   Oleg Nesterov   pidns: fix free_p...
140
141
  			/* Handle a fork failure of the first process */
  			WARN_ON(ns->child_reaper);
e8cfbc245   Gargi Sharma   pid: remove pidhash
142
  			ns->pid_allocated = 0;
314a8ad0f   Oleg Nesterov   pidns: fix free_p...
143
  			/* fall through */
af4b8a83a   Eric W. Biederman   pidns: Wait in za...
144
  		case 0:
af4b8a83a   Eric W. Biederman   pidns: Wait in za...
145
146
  			schedule_work(&ns->proc_work);
  			break;
5e1182deb   Eric W. Biederman   pidns: Don't allo...
147
  		}
95846ecf9   Gargi Sharma   pid: replace pid ...
148
149
  
  		idr_remove(&ns->idr, upid->nr);
0a01f2cc3   Eric W. Biederman   pidns: Make the p...
150
  	}
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
151
  	spin_unlock_irqrestore(&pidmap_lock, flags);
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
152
153
  	call_rcu(&pid->rcu, delayed_put_pid);
  }
8ef047aaa   Pavel Emelyanov   pid namespaces: m...
154
  struct pid *alloc_pid(struct pid_namespace *ns)
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
155
156
157
  {
  	struct pid *pid;
  	enum pid_type type;
8ef047aaa   Pavel Emelyanov   pid namespaces: m...
158
159
  	int i, nr;
  	struct pid_namespace *tmp;
198fe21b0   Pavel Emelyanov   pid namespaces: h...
160
  	struct upid *upid;
35f71bc0a   Michal Hocko   fork: report pid ...
161
  	int retval = -ENOMEM;
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
162

baf8f0f82   Pavel Emelianov   pid namespaces: d...
163
  	pid = kmem_cache_alloc(ns->pid_cachep, GFP_KERNEL);
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
164
  	if (!pid)
35f71bc0a   Michal Hocko   fork: report pid ...
165
  		return ERR_PTR(retval);
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
166

8ef047aaa   Pavel Emelyanov   pid namespaces: m...
167
  	tmp = ns;
0a01f2cc3   Eric W. Biederman   pidns: Make the p...
168
  	pid->level = ns->level;
95846ecf9   Gargi Sharma   pid: replace pid ...
169

8ef047aaa   Pavel Emelyanov   pid namespaces: m...
170
  	for (i = ns->level; i >= 0; i--) {
95846ecf9   Gargi Sharma   pid: replace pid ...
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
  		int pid_min = 1;
  
  		idr_preload(GFP_KERNEL);
  		spin_lock_irq(&pidmap_lock);
  
  		/*
  		 * init really needs pid 1, but after reaching the maximum
  		 * wrap back to RESERVED_PIDS
  		 */
  		if (idr_get_cursor(&tmp->idr) > RESERVED_PIDS)
  			pid_min = RESERVED_PIDS;
  
  		/*
  		 * Store a null pointer so find_pid_ns does not find
  		 * a partially initialized PID (see below).
  		 */
  		nr = idr_alloc_cyclic(&tmp->idr, NULL, pid_min,
  				      pid_max, GFP_ATOMIC);
  		spin_unlock_irq(&pidmap_lock);
  		idr_preload_end();
287980e49   Arnd Bergmann   remove lots of IS...
191
  		if (nr < 0) {
f83606f5e   KJ Tsanaktsidis   fork: report pid ...
192
  			retval = (nr == -ENOSPC) ? -EAGAIN : nr;
8ef047aaa   Pavel Emelyanov   pid namespaces: m...
193
  			goto out_free;
35f71bc0a   Michal Hocko   fork: report pid ...
194
  		}
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
195

8ef047aaa   Pavel Emelyanov   pid namespaces: m...
196
197
198
199
  		pid->numbers[i].nr = nr;
  		pid->numbers[i].ns = tmp;
  		tmp = tmp->parent;
  	}
0a01f2cc3   Eric W. Biederman   pidns: Make the p...
200
  	if (unlikely(is_child_reaper(pid))) {
c0ee55490   Eric W. Biederman   pid: Handle failu...
201
  		if (pid_ns_prepare_proc(ns))
0a01f2cc3   Eric W. Biederman   pidns: Make the p...
202
203
  			goto out_free;
  	}
b461cc038   Pavel Emelyanov   pid namespaces: m...
204
  	get_pid_ns(ns);
f57e515a1   Joel Fernandes (Google)   kernel/pid.c: con...
205
  	refcount_set(&pid->count, 1);
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
206
207
  	for (type = 0; type < PIDTYPE_MAX; ++type)
  		INIT_HLIST_HEAD(&pid->tasks[type]);
b53b0b9d9   Joel Fernandes (Google)   pidfd: add pollin...
208
  	init_waitqueue_head(&pid->wait_pidfd);
417e31524   André Goddard Rosa   pid: reduce code ...
209
  	upid = pid->numbers + ns->level;
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
210
  	spin_lock_irq(&pidmap_lock);
e8cfbc245   Gargi Sharma   pid: remove pidhash
211
  	if (!(ns->pid_allocated & PIDNS_ADDING))
5e1182deb   Eric W. Biederman   pidns: Don't allo...
212
  		goto out_unlock;
0a01f2cc3   Eric W. Biederman   pidns: Make the p...
213
  	for ( ; upid >= pid->numbers; --upid) {
95846ecf9   Gargi Sharma   pid: replace pid ...
214
215
  		/* Make the PID visible to find_pid_ns. */
  		idr_replace(&upid->ns->idr, pid, upid->nr);
e8cfbc245   Gargi Sharma   pid: remove pidhash
216
  		upid->ns->pid_allocated++;
0a01f2cc3   Eric W. Biederman   pidns: Make the p...
217
  	}
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
218
  	spin_unlock_irq(&pidmap_lock);
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
219
  	return pid;
5e1182deb   Eric W. Biederman   pidns: Don't allo...
220
  out_unlock:
6e6668845   Eric W. Biederman   kernel/pid.c: ree...
221
  	spin_unlock_irq(&pidmap_lock);
24c037ebf   Oleg Nesterov   exit: pidns: allo...
222
  	put_pid_ns(ns);
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
223
  out_free:
95846ecf9   Gargi Sharma   pid: replace pid ...
224
  	spin_lock_irq(&pidmap_lock);
1a80dade0   Matthew Wilcox   Fix failure path ...
225
226
227
228
  	while (++i <= ns->level) {
  		upid = pid->numbers + i;
  		idr_remove(&upid->ns->idr, upid->nr);
  	}
95846ecf9   Gargi Sharma   pid: replace pid ...
229

c0ee55490   Eric W. Biederman   pid: Handle failu...
230
231
232
  	/* On failure to allocate the first pid, reset the state */
  	if (ns->pid_allocated == PIDNS_ADDING)
  		idr_set_cursor(&ns->idr, 0);
95846ecf9   Gargi Sharma   pid: replace pid ...
233
  	spin_unlock_irq(&pidmap_lock);
8ef047aaa   Pavel Emelyanov   pid namespaces: m...
234

baf8f0f82   Pavel Emelianov   pid namespaces: d...
235
  	kmem_cache_free(ns->pid_cachep, pid);
35f71bc0a   Michal Hocko   fork: report pid ...
236
  	return ERR_PTR(retval);
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
237
  }
c876ad768   Eric W. Biederman   pidns: Stop pid a...
238
239
240
  void disable_pid_allocation(struct pid_namespace *ns)
  {
  	spin_lock_irq(&pidmap_lock);
e8cfbc245   Gargi Sharma   pid: remove pidhash
241
  	ns->pid_allocated &= ~PIDNS_ADDING;
c876ad768   Eric W. Biederman   pidns: Stop pid a...
242
243
  	spin_unlock_irq(&pidmap_lock);
  }
7ad5b3a50   Harvey Harrison   kernel: remove fa...
244
  struct pid *find_pid_ns(int nr, struct pid_namespace *ns)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
245
  {
e8cfbc245   Gargi Sharma   pid: remove pidhash
246
  	return idr_find(&ns->idr, nr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
247
  }
198fe21b0   Pavel Emelyanov   pid namespaces: h...
248
  EXPORT_SYMBOL_GPL(find_pid_ns);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
249

8990571eb   Pavel Emelyanov   Uninline find_pid...
250
251
  struct pid *find_vpid(int nr)
  {
17cf22c33   Eric W. Biederman   pidns: Use task_a...
252
  	return find_pid_ns(nr, task_active_pid_ns(current));
8990571eb   Pavel Emelyanov   Uninline find_pid...
253
254
  }
  EXPORT_SYMBOL_GPL(find_vpid);
2c4704756   Eric W. Biederman   pids: Move the pg...
255
256
257
258
  static struct pid **task_pid_ptr(struct task_struct *task, enum pid_type type)
  {
  	return (type == PIDTYPE_PID) ?
  		&task->thread_pid :
2c4704756   Eric W. Biederman   pids: Move the pg...
259
260
  		&task->signal->pids[type];
  }
e713d0dab   Sukadev Bhattiprolu   attach_pid() with...
261
262
263
  /*
   * attach_pid() must be called with the tasklist_lock write-held.
   */
819077398   Oleg Nesterov   kernel/fork.c:cop...
264
  void attach_pid(struct task_struct *task, enum pid_type type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265
  {
2c4704756   Eric W. Biederman   pids: Move the pg...
266
267
  	struct pid *pid = *task_pid_ptr(task, type);
  	hlist_add_head_rcu(&task->pid_links[type], &pid->tasks[type]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
268
  }
24336eaee   Oleg Nesterov   pids: introduce c...
269
270
  static void __change_pid(struct task_struct *task, enum pid_type type,
  			struct pid *new)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
271
  {
2c4704756   Eric W. Biederman   pids: Move the pg...
272
  	struct pid **pid_ptr = task_pid_ptr(task, type);
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
273
274
  	struct pid *pid;
  	int tmp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
275

2c4704756   Eric W. Biederman   pids: Move the pg...
276
  	pid = *pid_ptr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
277

2c4704756   Eric W. Biederman   pids: Move the pg...
278
279
  	hlist_del_rcu(&task->pid_links[type]);
  	*pid_ptr = new;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
280

92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
281
282
283
  	for (tmp = PIDTYPE_MAX; --tmp >= 0; )
  		if (!hlist_empty(&pid->tasks[tmp]))
  			return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
284

92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
285
  	free_pid(pid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
286
  }
24336eaee   Oleg Nesterov   pids: introduce c...
287
288
289
290
291
292
293
294
295
  void detach_pid(struct task_struct *task, enum pid_type type)
  {
  	__change_pid(task, type, NULL);
  }
  
  void change_pid(struct task_struct *task, enum pid_type type,
  		struct pid *pid)
  {
  	__change_pid(task, type, pid);
819077398   Oleg Nesterov   kernel/fork.c:cop...
296
  	attach_pid(task, type);
24336eaee   Oleg Nesterov   pids: introduce c...
297
  }
c18258c6f   Eric W. Biederman   [PATCH] pid: Impl...
298
  /* transfer_pid is an optimization of attach_pid(new), detach_pid(old) */
7ad5b3a50   Harvey Harrison   kernel: remove fa...
299
  void transfer_pid(struct task_struct *old, struct task_struct *new,
c18258c6f   Eric W. Biederman   [PATCH] pid: Impl...
300
301
  			   enum pid_type type)
  {
2c4704756   Eric W. Biederman   pids: Move the pg...
302
303
304
  	if (type == PIDTYPE_PID)
  		new->thread_pid = old->thread_pid;
  	hlist_replace_rcu(&old->pid_links[type], &new->pid_links[type]);
c18258c6f   Eric W. Biederman   [PATCH] pid: Impl...
305
  }
7ad5b3a50   Harvey Harrison   kernel: remove fa...
306
  struct task_struct *pid_task(struct pid *pid, enum pid_type type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
307
  {
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
308
309
310
  	struct task_struct *result = NULL;
  	if (pid) {
  		struct hlist_node *first;
67bdbffd6   Arnd Bergmann   rculist: avoid __...
311
  		first = rcu_dereference_check(hlist_first_rcu(&pid->tasks[type]),
db1466b3e   Paul E. McKenney   rcu: Use wrapper ...
312
  					      lockdep_tasklist_lock_is_held());
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
313
  		if (first)
2c4704756   Eric W. Biederman   pids: Move the pg...
314
  			result = hlist_entry(first, struct task_struct, pid_links[(type)]);
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
315
316
317
  	}
  	return result;
  }
eccba0689   Pavel Emelyanov   gfs2: make gfs2_g...
318
  EXPORT_SYMBOL(pid_task);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
319

92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
320
  /*
9728e5d6e   Tetsuo Handa   kernel/pid.c: upd...
321
   * Must be called under rcu_read_lock().
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
322
   */
17f98dcf6   Christoph Hellwig   pids: clean up fi...
323
  struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns)
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
324
  {
f78f5b90c   Paul E. McKenney   rcu: Rename rcu_l...
325
326
  	RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
  			 "find_task_by_pid_ns() needs rcu_read_lock() protection");
17f98dcf6   Christoph Hellwig   pids: clean up fi...
327
  	return pid_task(find_pid_ns(nr, ns), PIDTYPE_PID);
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
328
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
329

228ebcbe6   Pavel Emelyanov   Uninline find_tas...
330
331
  struct task_struct *find_task_by_vpid(pid_t vnr)
  {
17cf22c33   Eric W. Biederman   pidns: Use task_a...
332
  	return find_task_by_pid_ns(vnr, task_active_pid_ns(current));
228ebcbe6   Pavel Emelyanov   Uninline find_tas...
333
  }
228ebcbe6   Pavel Emelyanov   Uninline find_tas...
334

2ee082608   Mike Rapoport   pids: introduce f...
335
336
337
338
339
340
341
342
343
344
345
346
  struct task_struct *find_get_task_by_vpid(pid_t nr)
  {
  	struct task_struct *task;
  
  	rcu_read_lock();
  	task = find_task_by_vpid(nr);
  	if (task)
  		get_task_struct(task);
  	rcu_read_unlock();
  
  	return task;
  }
1a657f78d   Oleg Nesterov   [PATCH] introduce...
347
348
349
350
  struct pid *get_task_pid(struct task_struct *task, enum pid_type type)
  {
  	struct pid *pid;
  	rcu_read_lock();
2c4704756   Eric W. Biederman   pids: Move the pg...
351
  	pid = get_pid(rcu_dereference(*task_pid_ptr(task, type)));
1a657f78d   Oleg Nesterov   [PATCH] introduce...
352
353
354
  	rcu_read_unlock();
  	return pid;
  }
77c100c83   Rik van Riel   export pid symbol...
355
  EXPORT_SYMBOL_GPL(get_task_pid);
1a657f78d   Oleg Nesterov   [PATCH] introduce...
356

7ad5b3a50   Harvey Harrison   kernel: remove fa...
357
  struct task_struct *get_pid_task(struct pid *pid, enum pid_type type)
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
358
359
360
361
362
363
364
365
  {
  	struct task_struct *result;
  	rcu_read_lock();
  	result = pid_task(pid, type);
  	if (result)
  		get_task_struct(result);
  	rcu_read_unlock();
  	return result;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
366
  }
77c100c83   Rik van Riel   export pid symbol...
367
  EXPORT_SYMBOL_GPL(get_pid_task);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
368

92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
369
  struct pid *find_get_pid(pid_t nr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
370
371
  {
  	struct pid *pid;
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
372
  	rcu_read_lock();
198fe21b0   Pavel Emelyanov   pid namespaces: h...
373
  	pid = get_pid(find_vpid(nr));
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
374
  	rcu_read_unlock();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
375

92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
376
  	return pid;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
377
  }
339caf2a2   David Sterba   proc: misplaced e...
378
  EXPORT_SYMBOL_GPL(find_get_pid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
379

7af572947   Pavel Emelyanov   pid namespaces: h...
380
381
382
383
384
385
386
387
388
389
390
391
  pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns)
  {
  	struct upid *upid;
  	pid_t nr = 0;
  
  	if (pid && ns->level <= pid->level) {
  		upid = &pid->numbers[ns->level];
  		if (upid->ns == ns)
  			nr = upid->nr;
  	}
  	return nr;
  }
4f82f4573   Eric W. Biederman   net ip6 flowlabel...
392
  EXPORT_SYMBOL_GPL(pid_nr_ns);
7af572947   Pavel Emelyanov   pid namespaces: h...
393

44c4e1b25   Eric W. Biederman   pid: Extend/Fix p...
394
395
  pid_t pid_vnr(struct pid *pid)
  {
17cf22c33   Eric W. Biederman   pidns: Use task_a...
396
  	return pid_nr_ns(pid, task_active_pid_ns(current));
44c4e1b25   Eric W. Biederman   pid: Extend/Fix p...
397
398
  }
  EXPORT_SYMBOL_GPL(pid_vnr);
52ee2dfdd   Oleg Nesterov   pids: refactor vn...
399
400
  pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type,
  			struct pid_namespace *ns)
2f2a3a46f   Pavel Emelyanov   Uninline the task...
401
  {
52ee2dfdd   Oleg Nesterov   pids: refactor vn...
402
403
404
405
  	pid_t nr = 0;
  
  	rcu_read_lock();
  	if (!ns)
17cf22c33   Eric W. Biederman   pidns: Use task_a...
406
  		ns = task_active_pid_ns(current);
2c4704756   Eric W. Biederman   pids: Move the pg...
407
408
  	if (likely(pid_alive(task)))
  		nr = pid_nr_ns(rcu_dereference(*task_pid_ptr(task, type)), ns);
52ee2dfdd   Oleg Nesterov   pids: refactor vn...
409
410
411
  	rcu_read_unlock();
  
  	return nr;
2f2a3a46f   Pavel Emelyanov   Uninline the task...
412
  }
52ee2dfdd   Oleg Nesterov   pids: refactor vn...
413
  EXPORT_SYMBOL(__task_pid_nr_ns);
2f2a3a46f   Pavel Emelyanov   Uninline the task...
414

61bce0f13   Eric W. Biederman   pid: generalize t...
415
416
417
418
419
  struct pid_namespace *task_active_pid_ns(struct task_struct *tsk)
  {
  	return ns_of_pid(task_pid(tsk));
  }
  EXPORT_SYMBOL_GPL(task_active_pid_ns);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
420
  /*
025dfdafe   Frederik Schwarzer   trivial: fix then...
421
   * Used by proc to find the first pid that is greater than or equal to nr.
0804ef4b0   Eric W. Biederman   [PATCH] proc: rea...
422
   *
e49859e71   Pavel Emelyanov   pidns: remove now...
423
   * If there is a pid at nr this function is exactly the same as find_pid_ns.
0804ef4b0   Eric W. Biederman   [PATCH] proc: rea...
424
   */
198fe21b0   Pavel Emelyanov   pid namespaces: h...
425
  struct pid *find_ge_pid(int nr, struct pid_namespace *ns)
0804ef4b0   Eric W. Biederman   [PATCH] proc: rea...
426
  {
95846ecf9   Gargi Sharma   pid: replace pid ...
427
  	return idr_get_next(&ns->idr, &nr);
0804ef4b0   Eric W. Biederman   [PATCH] proc: rea...
428
  }
32fcb426e   Christian Brauner   pid: add pidfd_op...
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
  /**
   * pidfd_create() - Create a new pid file descriptor.
   *
   * @pid:  struct pid that the pidfd will reference
   *
   * This creates a new pid file descriptor with the O_CLOEXEC flag set.
   *
   * Note, that this function can only be called after the fd table has
   * been unshared to avoid leaking the pidfd to the new process.
   *
   * Return: On success, a cloexec pidfd is returned.
   *         On error, a negative errno number will be returned.
   */
  static int pidfd_create(struct pid *pid)
  {
  	int fd;
  
  	fd = anon_inode_getfd("[pidfd]", &pidfd_fops, get_pid(pid),
  			      O_RDWR | O_CLOEXEC);
  	if (fd < 0)
  		put_pid(pid);
  
  	return fd;
  }
  
  /**
   * pidfd_open() - Open new pid file descriptor.
   *
   * @pid:   pid for which to retrieve a pidfd
   * @flags: flags to pass
   *
   * This creates a new pid file descriptor with the O_CLOEXEC flag set for
   * the process identified by @pid. Currently, the process identified by
   * @pid must be a thread-group leader. This restriction currently exists
   * for all aspects of pidfds including pidfd creation (CLONE_PIDFD cannot
   * be used with CLONE_THREAD) and pidfd polling (only supports thread group
   * leaders).
   *
   * Return: On success, a cloexec pidfd is returned.
   *         On error, a negative errno number will be returned.
   */
  SYSCALL_DEFINE2(pidfd_open, pid_t, pid, unsigned int, flags)
  {
  	int fd, ret;
  	struct pid *p;
  
  	if (flags)
  		return -EINVAL;
  
  	if (pid <= 0)
  		return -EINVAL;
  
  	p = find_get_pid(pid);
  	if (!p)
  		return -ESRCH;
  
  	ret = 0;
  	rcu_read_lock();
  	if (!pid_task(p, PIDTYPE_TGID))
  		ret = -EINVAL;
  	rcu_read_unlock();
  
  	fd = ret ?: pidfd_create(p);
  	put_pid(p);
  	return fd;
  }
95846ecf9   Gargi Sharma   pid: replace pid ...
495
  void __init pid_idr_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
496
  {
840d6fe74   Zhen Lei   pid: Fix spelling...
497
  	/* Verify no one has done anything silly: */
e8cfbc245   Gargi Sharma   pid: remove pidhash
498
  	BUILD_BUG_ON(PID_MAX_LIMIT >= PIDNS_ADDING);
c876ad768   Eric W. Biederman   pidns: Stop pid a...
499

72680a191   Hedi Berriche   pids: increase pi...
500
501
502
503
504
505
506
  	/* bump default and minimum pid_max based on number of cpus */
  	pid_max = min(pid_max_max, max_t(int, pid_max,
  				PIDS_PER_CPU_DEFAULT * num_possible_cpus()));
  	pid_max_min = max_t(int, pid_max_min,
  				PIDS_PER_CPU_MIN * num_possible_cpus());
  	pr_info("pid_max: default: %u minimum: %u
  ", pid_max, pid_max_min);
95846ecf9   Gargi Sharma   pid: replace pid ...
507
  	idr_init(&init_pid_ns.idr);
92476d7fc   Eric W. Biederman   [PATCH] pidhash: ...
508

74bd59bb3   Pavel Emelyanov   namespaces: clean...
509
  	init_pid_ns.pid_cachep = KMEM_CACHE(pid,
5d097056c   Vladimir Davydov   kmemcg: account c...
510
  			SLAB_HWCACHE_ALIGN | SLAB_PANIC | SLAB_ACCOUNT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
511
  }