Lines Matching +full:key +full:- +full:wakeup

1 // SPDX-License-Identifier: GPL-2.0-or-later
64 * smp_mb(); (A) <-- paired with -.
73 * `--------> smp_mb(); (B)
80 * waiters--; (b) unlock(hash_bucket(futex));
104 * acquiring the lock. It then decrements them again after releasing it -
112 if (WARN(q->pi_state || q->rt_waiter, "refusing to wake PI futex\n")) in __futex_wake_mark()
117 * The waiting task can free the futex_q as soon as q->lock_ptr = NULL in __futex_wake_mark()
119 * of a spurious wakeup, for example. A memory barrier is required here in __futex_wake_mark()
123 smp_store_release(&q->lock_ptr, NULL); in __futex_wake_mark()
136 struct task_struct *p = q->task; in futex_wake_mark()
146 * Queue the task for later wakeup for after we've released in futex_wake_mark()
147 * the hb->lock. in futex_wake_mark()
159 union futex_key key = FUTEX_KEY_INIT; in futex_wake() local
164 return -EINVAL; in futex_wake()
166 ret = get_futex_key(uaddr, flags, &key, FUTEX_READ); in futex_wake()
173 hb = futex_hash(&key); in futex_wake()
175 /* Make sure we really have tasks to wakeup */ in futex_wake()
179 spin_lock(&hb->lock); in futex_wake()
181 plist_for_each_entry_safe(this, next, &hb->chain, list) { in futex_wake()
182 if (futex_match (&this->key, &key)) { in futex_wake()
183 if (this->pi_state || this->rt_waiter) { in futex_wake()
184 ret = -EINVAL; in futex_wake()
189 if (!(this->bitset & bitset)) in futex_wake()
192 this->wake(&wake_q, this); in futex_wake()
198 spin_unlock(&hb->lock); in futex_wake()
214 * kill this print and return -EINVAL when userspace in futex_atomic_op_inuser()
218 current->comm, oparg); in futex_atomic_op_inuser()
244 return -ENOSYS; in futex_atomic_op_inuser()
279 unlikely(op_ret != -EFAULT && op_ret != -EAGAIN)) { in futex_wake_op()
288 if (op_ret == -EFAULT) { in futex_wake_op()
300 plist_for_each_entry_safe(this, next, &hb1->chain, list) { in futex_wake_op()
301 if (futex_match (&this->key, &key1)) { in futex_wake_op()
302 if (this->pi_state || this->rt_waiter) { in futex_wake_op()
303 ret = -EINVAL; in futex_wake_op()
306 this->wake(&wake_q, this); in futex_wake_op()
314 plist_for_each_entry_safe(this, next, &hb2->chain, list) { in futex_wake_op()
315 if (futex_match (&this->key, &key2)) { in futex_wake_op()
316 if (this->pi_state || this->rt_waiter) { in futex_wake_op()
317 ret = -EINVAL; in futex_wake_op()
320 this->wake(&wake_q, this); in futex_wake_op()
337 * futex_wait_queue() - futex_queue() and wait for wakeup, timeout, or signal
362 if (likely(!plist_node_empty(&q->list))) { in futex_wait_queue()
368 if (!timeout || timeout->task) in futex_wait_queue()
375 * futex_unqueue_multiple - Remove various futexes from their hash bucket
382 * - >=0 - Index of the last futex that was awoken;
383 * - -1 - No futex was awoken
387 int ret = -1, i; in futex_unqueue_multiple()
398 * futex_wait_multiple_setup - Prepare to wait and enqueue multiple futexes
409 * - 1 - One of the futexes was woken by another thread
410 * - 0 - Success
411 * - <0 - -EFAULT, -EWOULDBLOCK or -EINVAL
424 * make sure that current->state is TASK_INTERRUPTIBLE, so we don't in futex_wait_multiple_setup()
426 * of the next key, because it calls get_user_pages, which can sleep. in futex_wait_multiple_setup()
428 * pinning all the memory keys in the futex key, and only then we read in futex_wait_multiple_setup()
429 * each key and queue the corresponding futex. in futex_wait_multiple_setup()
441 &vs[i].q.key, FUTEX_READ); in futex_wait_multiple_setup()
483 * we could lose some wakeup). So we do it here, after in futex_wait_multiple_setup()
488 return -EFAULT; in futex_wait_multiple_setup()
495 return -EWOULDBLOCK; in futex_wait_multiple_setup()
502 * futex_sleep_multiple - Check sleeping conditions and sleep
513 if (to && !to->task) in futex_sleep_multiple()
516 for (; count; count--, vs++) { in futex_sleep_multiple()
517 if (!READ_ONCE(vs->q.lock_ptr)) in futex_sleep_multiple()
525 * futex_wait_multiple - Prepare to wait on and enqueue several futexes
535 * - >=0 - Hint to the futex that was awoken
536 * - <0 - On error
564 if (to && !to->task) in futex_wait_multiple()
565 return -ETIMEDOUT; in futex_wait_multiple()
567 return -ERESTARTSYS; in futex_wait_multiple()
569 * The final case is a spurious wakeup, for in futex_wait_multiple()
576 * futex_wait_setup() - Prepare to wait on a futex
588 * - 0 - uaddr contains val and hb has been locked;
589 * - <1 - -EFAULT or -EWOULDBLOCK (uaddr does not contain val) and hb is unlocked
598 * Access the page AFTER the hash-bucket is locked. in futex_wait_setup()
606 * any cond. If we locked the hash-bucket after testing *uaddr, that in futex_wait_setup()
610 * On the other hand, we insert q and release the hash-bucket only in futex_wait_setup()
612 * absorb a wakeup if *uaddr does not match the desired values in futex_wait_setup()
616 ret = get_futex_key(uaddr, flags, &q->key, FUTEX_READ); in futex_wait_setup()
640 ret = -EWOULDBLOCK; in futex_wait_setup()
654 return -EINVAL; in __futex_wait()
660 * Prepare to wait on uaddr. On success, it holds hb->lock and q in __futex_wait()
667 /* futex_queue and wait for wakeup, timeout, or a signal. */ in __futex_wait()
674 if (to && !to->task) in __futex_wait()
675 return -ETIMEDOUT; in __futex_wait()
679 * victim of a spurious wakeup as well. in __futex_wait()
684 return -ERESTARTSYS; in __futex_wait()
694 current->timer_slack_ns); in futex_wait()
702 hrtimer_cancel(&to->timer); in futex_wait()
703 destroy_hrtimer_on_stack(&to->timer); in futex_wait()
705 if (ret == -ERESTARTSYS) { in futex_wait()
706 restart = &current->restart_block; in futex_wait()
707 restart->futex.uaddr = uaddr; in futex_wait()
708 restart->futex.val = val; in futex_wait()
709 restart->futex.time = *abs_time; in futex_wait()
710 restart->futex.bitset = bitset; in futex_wait()
711 restart->futex.flags = flags | FLAGS_HAS_TIMEOUT; in futex_wait()
721 u32 __user *uaddr = restart->futex.uaddr; in futex_wait_restart()
724 if (restart->futex.flags & FLAGS_HAS_TIMEOUT) { in futex_wait_restart()
725 t = restart->futex.time; in futex_wait_restart()
728 restart->fn = do_no_restart_syscall; in futex_wait_restart()
730 return (long)futex_wait(uaddr, restart->futex.flags, in futex_wait_restart()
731 restart->futex.val, tp, restart->futex.bitset); in futex_wait_restart()