Lines Matching +full:left +full:- +full:most

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Generic pidhash and scalable, time-bounded PID allocator
5 * (C) 2002-2003 Nadia Yvette Chambers, IBM
7 * (C) 2002-2004 Ingo Molnar, Red Hat
9 * pid-structures are backing objects for tasks sharing a given ID to chain
13 * The hash is always changed with the tasklist_lock write-acquired,
15 * read-acquired, so there's no additional SMP locking needed here.
18 * Allocating and freeing PIDs is completely lockless. The worst-case
20 * allocated already: the scanning of 32 list entries and at most PAGE_SIZE
70 * PID-map pages start out as NULL, they get allocated upon
97 * detach_pid()->free_pid() and another cpu that does
115 ns = pid->numbers[pid->level].ns; in put_pid()
116 if (refcount_dec_and_test(&pid->count)) { in put_pid()
117 kmem_cache_free(ns->pid_cachep, pid); in put_pid()
136 for (i = 0; i <= pid->level; i++) { in free_pid()
137 struct upid *upid = pid->numbers + i; in free_pid()
138 struct pid_namespace *ns = upid->ns; in free_pid()
139 switch (--ns->pid_allocated) { in free_pid()
142 /* When all that is left in the pid namespace in free_pid()
146 wake_up_process(ns->child_reaper); in free_pid()
150 WARN_ON(ns->child_reaper); in free_pid()
151 ns->pid_allocated = 0; in free_pid()
155 idr_remove(&ns->idr, upid->nr); in free_pid()
159 call_rcu(&pid->rcu, delayed_put_pid); in free_pid()
170 int retval = -ENOMEM; in alloc_pid()
174 * the most nested currently active PID namespace it tells alloc_pid() in alloc_pid()
175 * which PID to set for a process in that most nested PID namespace in alloc_pid()
178 * never be greater than the current ns->level + 1. in alloc_pid()
180 if (set_tid_size > ns->level + 1) in alloc_pid()
181 return ERR_PTR(-EINVAL); in alloc_pid()
183 pid = kmem_cache_alloc(ns->pid_cachep, GFP_KERNEL); in alloc_pid()
188 pid->level = ns->level; in alloc_pid()
190 for (i = ns->level; i >= 0; i--) { in alloc_pid()
194 tid = set_tid[ns->level - i]; in alloc_pid()
196 retval = -EINVAL; in alloc_pid()
203 if (tid != 1 && !tmp->child_reaper) in alloc_pid()
205 retval = -EPERM; in alloc_pid()
206 if (!checkpoint_restore_ns_capable(tmp->user_ns)) in alloc_pid()
208 set_tid_size--; in alloc_pid()
215 nr = idr_alloc(&tmp->idr, NULL, tid, in alloc_pid()
221 if (nr == -ENOSPC) in alloc_pid()
222 nr = -EEXIST; in alloc_pid()
229 if (idr_get_cursor(&tmp->idr) > RESERVED_PIDS) in alloc_pid()
236 nr = idr_alloc_cyclic(&tmp->idr, NULL, pid_min, in alloc_pid()
243 retval = (nr == -ENOSPC) ? -EAGAIN : nr; in alloc_pid()
247 pid->numbers[i].nr = nr; in alloc_pid()
248 pid->numbers[i].ns = tmp; in alloc_pid()
249 tmp = tmp->parent; in alloc_pid()
253 * ENOMEM is not the most obvious choice especially for the case in alloc_pid()
260 retval = -ENOMEM; in alloc_pid()
263 refcount_set(&pid->count, 1); in alloc_pid()
264 spin_lock_init(&pid->lock); in alloc_pid()
266 INIT_HLIST_HEAD(&pid->tasks[type]); in alloc_pid()
268 init_waitqueue_head(&pid->wait_pidfd); in alloc_pid()
269 INIT_HLIST_HEAD(&pid->inodes); in alloc_pid()
271 upid = pid->numbers + ns->level; in alloc_pid()
273 if (!(ns->pid_allocated & PIDNS_ADDING)) in alloc_pid()
275 for ( ; upid >= pid->numbers; --upid) { in alloc_pid()
277 idr_replace(&upid->ns->idr, pid, upid->nr); in alloc_pid()
278 upid->ns->pid_allocated++; in alloc_pid()
290 while (++i <= ns->level) { in alloc_pid()
291 upid = pid->numbers + i; in alloc_pid()
292 idr_remove(&upid->ns->idr, upid->nr); in alloc_pid()
296 if (ns->pid_allocated == PIDNS_ADDING) in alloc_pid()
297 idr_set_cursor(&ns->idr, 0); in alloc_pid()
301 kmem_cache_free(ns->pid_cachep, pid); in alloc_pid()
308 ns->pid_allocated &= ~PIDNS_ADDING; in disable_pid_allocation()
314 return idr_find(&ns->idr, nr); in find_pid_ns()
327 &task->thread_pid : in task_pid_ptr()
328 &task->signal->pids[type]; in task_pid_ptr()
332 * attach_pid() must be called with the tasklist_lock write-held.
337 hlist_add_head_rcu(&task->pid_links[type], &pid->tasks[type]); in attach_pid()
349 hlist_del_rcu(&task->pid_links[type]); in __change_pid()
352 for (tmp = PIDTYPE_MAX; --tmp >= 0; ) in __change_pid()
371 void exchange_tids(struct task_struct *left, struct task_struct *right) in exchange_tids() argument
373 struct pid *pid1 = left->thread_pid; in exchange_tids()
374 struct pid *pid2 = right->thread_pid; in exchange_tids()
375 struct hlist_head *head1 = &pid1->tasks[PIDTYPE_PID]; in exchange_tids()
376 struct hlist_head *head2 = &pid2->tasks[PIDTYPE_PID]; in exchange_tids()
382 rcu_assign_pointer(left->thread_pid, pid2); in exchange_tids()
383 rcu_assign_pointer(right->thread_pid, pid1); in exchange_tids()
386 WRITE_ONCE(left->pid, pid_nr(pid2)); in exchange_tids()
387 WRITE_ONCE(right->pid, pid_nr(pid1)); in exchange_tids()
395 new->thread_pid = old->thread_pid; in transfer_pid()
396 hlist_replace_rcu(&old->pid_links[type], &new->pid_links[type]); in transfer_pid()
404 first = rcu_dereference_check(hlist_first_rcu(&pid->tasks[type]), in pid_task()
480 if (pid && ns->level <= pid->level) { in pid_nr_ns()
481 upid = &pid->numbers[ns->level]; in pid_nr_ns()
482 if (upid->ns == ns) in pid_nr_ns()
483 nr = upid->nr; in pid_nr_ns()
523 return idr_get_next(&ns->idr, &nr); in find_ge_pid()
534 return ERR_PTR(-EBADF); in pidfd_get_pid()
539 *flags = f.file->f_flags; in pidfd_get_pid()
547 * pidfd_get_task() - Get the task associated with a pidfd
555 * Currently, the process identified by @pidfd is always a thread-group leader.
576 return ERR_PTR(-ESRCH); in pidfd_get_task()
583 * pidfd_create() - Create a new pid file descriptor.
612 * sys_pidfd_open() - Open new pid file descriptor.
619 * @pid must be a thread-group leader. This restriction currently exists
633 return -EINVAL; in SYSCALL_DEFINE2()
636 return -EINVAL; in SYSCALL_DEFINE2()
640 return -ESRCH; in SYSCALL_DEFINE2()
674 ret = down_read_killable(&task->signal->exec_update_lock); in __pidfd_fget()
681 file = ERR_PTR(-EPERM); in __pidfd_fget()
683 up_read(&task->signal->exec_update_lock); in __pidfd_fget()
685 return file ?: ERR_PTR(-EBADF); in __pidfd_fget()
696 return -ESRCH; in pidfd_getfd()
710 * sys_pidfd_getfd() - Get a file descriptor from another process
732 /* flags is currently unused - make sure it's unset */ in SYSCALL_DEFINE3()
734 return -EINVAL; in SYSCALL_DEFINE3()
738 return -EBADF; in SYSCALL_DEFINE3()