162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef _LINUX_WAIT_BIT_H
362306a36Sopenharmony_ci#define _LINUX_WAIT_BIT_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci/*
662306a36Sopenharmony_ci * Linux wait-bit related types and methods:
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci#include <linux/wait.h>
962306a36Sopenharmony_ci
1062306a36Sopenharmony_cistruct wait_bit_key {
1162306a36Sopenharmony_ci	void			*flags;
1262306a36Sopenharmony_ci	int			bit_nr;
1362306a36Sopenharmony_ci	unsigned long		timeout;
1462306a36Sopenharmony_ci};
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_cistruct wait_bit_queue_entry {
1762306a36Sopenharmony_ci	struct wait_bit_key	key;
1862306a36Sopenharmony_ci	struct wait_queue_entry	wq_entry;
1962306a36Sopenharmony_ci};
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci#define __WAIT_BIT_KEY_INITIALIZER(word, bit)					\
2262306a36Sopenharmony_ci	{ .flags = word, .bit_nr = bit, }
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_citypedef int wait_bit_action_f(struct wait_bit_key *key, int mode);
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_civoid __wake_up_bit(struct wait_queue_head *wq_head, void *word, int bit);
2762306a36Sopenharmony_ciint __wait_on_bit(struct wait_queue_head *wq_head, struct wait_bit_queue_entry *wbq_entry, wait_bit_action_f *action, unsigned int mode);
2862306a36Sopenharmony_ciint __wait_on_bit_lock(struct wait_queue_head *wq_head, struct wait_bit_queue_entry *wbq_entry, wait_bit_action_f *action, unsigned int mode);
2962306a36Sopenharmony_civoid wake_up_bit(void *word, int bit);
3062306a36Sopenharmony_ciint out_of_line_wait_on_bit(void *word, int, wait_bit_action_f *action, unsigned int mode);
3162306a36Sopenharmony_ciint out_of_line_wait_on_bit_timeout(void *word, int, wait_bit_action_f *action, unsigned int mode, unsigned long timeout);
3262306a36Sopenharmony_ciint out_of_line_wait_on_bit_lock(void *word, int, wait_bit_action_f *action, unsigned int mode);
3362306a36Sopenharmony_cistruct wait_queue_head *bit_waitqueue(void *word, int bit);
3462306a36Sopenharmony_ciextern void __init wait_bit_init(void);
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ciint wake_bit_function(struct wait_queue_entry *wq_entry, unsigned mode, int sync, void *key);
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci#define DEFINE_WAIT_BIT(name, word, bit)					\
3962306a36Sopenharmony_ci	struct wait_bit_queue_entry name = {					\
4062306a36Sopenharmony_ci		.key = __WAIT_BIT_KEY_INITIALIZER(word, bit),			\
4162306a36Sopenharmony_ci		.wq_entry = {							\
4262306a36Sopenharmony_ci			.private	= current,				\
4362306a36Sopenharmony_ci			.func		= wake_bit_function,			\
4462306a36Sopenharmony_ci			.entry		=					\
4562306a36Sopenharmony_ci				LIST_HEAD_INIT((name).wq_entry.entry),		\
4662306a36Sopenharmony_ci		},								\
4762306a36Sopenharmony_ci	}
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ciextern int bit_wait(struct wait_bit_key *key, int mode);
5062306a36Sopenharmony_ciextern int bit_wait_io(struct wait_bit_key *key, int mode);
5162306a36Sopenharmony_ciextern int bit_wait_timeout(struct wait_bit_key *key, int mode);
5262306a36Sopenharmony_ciextern int bit_wait_io_timeout(struct wait_bit_key *key, int mode);
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci/**
5562306a36Sopenharmony_ci * wait_on_bit - wait for a bit to be cleared
5662306a36Sopenharmony_ci * @word: the word being waited on, a kernel virtual address
5762306a36Sopenharmony_ci * @bit: the bit of the word being waited on
5862306a36Sopenharmony_ci * @mode: the task state to sleep in
5962306a36Sopenharmony_ci *
6062306a36Sopenharmony_ci * There is a standard hashed waitqueue table for generic use. This
6162306a36Sopenharmony_ci * is the part of the hashtable's accessor API that waits on a bit.
6262306a36Sopenharmony_ci * For instance, if one were to have waiters on a bitflag, one would
6362306a36Sopenharmony_ci * call wait_on_bit() in threads waiting for the bit to clear.
6462306a36Sopenharmony_ci * One uses wait_on_bit() where one is waiting for the bit to clear,
6562306a36Sopenharmony_ci * but has no intention of setting it.
6662306a36Sopenharmony_ci * Returned value will be zero if the bit was cleared, or non-zero
6762306a36Sopenharmony_ci * if the process received a signal and the mode permitted wakeup
6862306a36Sopenharmony_ci * on that signal.
6962306a36Sopenharmony_ci */
7062306a36Sopenharmony_cistatic inline int
7162306a36Sopenharmony_ciwait_on_bit(unsigned long *word, int bit, unsigned mode)
7262306a36Sopenharmony_ci{
7362306a36Sopenharmony_ci	might_sleep();
7462306a36Sopenharmony_ci	if (!test_bit_acquire(bit, word))
7562306a36Sopenharmony_ci		return 0;
7662306a36Sopenharmony_ci	return out_of_line_wait_on_bit(word, bit,
7762306a36Sopenharmony_ci				       bit_wait,
7862306a36Sopenharmony_ci				       mode);
7962306a36Sopenharmony_ci}
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci/**
8262306a36Sopenharmony_ci * wait_on_bit_io - wait for a bit to be cleared
8362306a36Sopenharmony_ci * @word: the word being waited on, a kernel virtual address
8462306a36Sopenharmony_ci * @bit: the bit of the word being waited on
8562306a36Sopenharmony_ci * @mode: the task state to sleep in
8662306a36Sopenharmony_ci *
8762306a36Sopenharmony_ci * Use the standard hashed waitqueue table to wait for a bit
8862306a36Sopenharmony_ci * to be cleared.  This is similar to wait_on_bit(), but calls
8962306a36Sopenharmony_ci * io_schedule() instead of schedule() for the actual waiting.
9062306a36Sopenharmony_ci *
9162306a36Sopenharmony_ci * Returned value will be zero if the bit was cleared, or non-zero
9262306a36Sopenharmony_ci * if the process received a signal and the mode permitted wakeup
9362306a36Sopenharmony_ci * on that signal.
9462306a36Sopenharmony_ci */
9562306a36Sopenharmony_cistatic inline int
9662306a36Sopenharmony_ciwait_on_bit_io(unsigned long *word, int bit, unsigned mode)
9762306a36Sopenharmony_ci{
9862306a36Sopenharmony_ci	might_sleep();
9962306a36Sopenharmony_ci	if (!test_bit_acquire(bit, word))
10062306a36Sopenharmony_ci		return 0;
10162306a36Sopenharmony_ci	return out_of_line_wait_on_bit(word, bit,
10262306a36Sopenharmony_ci				       bit_wait_io,
10362306a36Sopenharmony_ci				       mode);
10462306a36Sopenharmony_ci}
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci/**
10762306a36Sopenharmony_ci * wait_on_bit_timeout - wait for a bit to be cleared or a timeout elapses
10862306a36Sopenharmony_ci * @word: the word being waited on, a kernel virtual address
10962306a36Sopenharmony_ci * @bit: the bit of the word being waited on
11062306a36Sopenharmony_ci * @mode: the task state to sleep in
11162306a36Sopenharmony_ci * @timeout: timeout, in jiffies
11262306a36Sopenharmony_ci *
11362306a36Sopenharmony_ci * Use the standard hashed waitqueue table to wait for a bit
11462306a36Sopenharmony_ci * to be cleared. This is similar to wait_on_bit(), except also takes a
11562306a36Sopenharmony_ci * timeout parameter.
11662306a36Sopenharmony_ci *
11762306a36Sopenharmony_ci * Returned value will be zero if the bit was cleared before the
11862306a36Sopenharmony_ci * @timeout elapsed, or non-zero if the @timeout elapsed or process
11962306a36Sopenharmony_ci * received a signal and the mode permitted wakeup on that signal.
12062306a36Sopenharmony_ci */
12162306a36Sopenharmony_cistatic inline int
12262306a36Sopenharmony_ciwait_on_bit_timeout(unsigned long *word, int bit, unsigned mode,
12362306a36Sopenharmony_ci		    unsigned long timeout)
12462306a36Sopenharmony_ci{
12562306a36Sopenharmony_ci	might_sleep();
12662306a36Sopenharmony_ci	if (!test_bit_acquire(bit, word))
12762306a36Sopenharmony_ci		return 0;
12862306a36Sopenharmony_ci	return out_of_line_wait_on_bit_timeout(word, bit,
12962306a36Sopenharmony_ci					       bit_wait_timeout,
13062306a36Sopenharmony_ci					       mode, timeout);
13162306a36Sopenharmony_ci}
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci/**
13462306a36Sopenharmony_ci * wait_on_bit_action - wait for a bit to be cleared
13562306a36Sopenharmony_ci * @word: the word being waited on, a kernel virtual address
13662306a36Sopenharmony_ci * @bit: the bit of the word being waited on
13762306a36Sopenharmony_ci * @action: the function used to sleep, which may take special actions
13862306a36Sopenharmony_ci * @mode: the task state to sleep in
13962306a36Sopenharmony_ci *
14062306a36Sopenharmony_ci * Use the standard hashed waitqueue table to wait for a bit
14162306a36Sopenharmony_ci * to be cleared, and allow the waiting action to be specified.
14262306a36Sopenharmony_ci * This is like wait_on_bit() but allows fine control of how the waiting
14362306a36Sopenharmony_ci * is done.
14462306a36Sopenharmony_ci *
14562306a36Sopenharmony_ci * Returned value will be zero if the bit was cleared, or non-zero
14662306a36Sopenharmony_ci * if the process received a signal and the mode permitted wakeup
14762306a36Sopenharmony_ci * on that signal.
14862306a36Sopenharmony_ci */
14962306a36Sopenharmony_cistatic inline int
15062306a36Sopenharmony_ciwait_on_bit_action(unsigned long *word, int bit, wait_bit_action_f *action,
15162306a36Sopenharmony_ci		   unsigned mode)
15262306a36Sopenharmony_ci{
15362306a36Sopenharmony_ci	might_sleep();
15462306a36Sopenharmony_ci	if (!test_bit_acquire(bit, word))
15562306a36Sopenharmony_ci		return 0;
15662306a36Sopenharmony_ci	return out_of_line_wait_on_bit(word, bit, action, mode);
15762306a36Sopenharmony_ci}
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ci/**
16062306a36Sopenharmony_ci * wait_on_bit_lock - wait for a bit to be cleared, when wanting to set it
16162306a36Sopenharmony_ci * @word: the word being waited on, a kernel virtual address
16262306a36Sopenharmony_ci * @bit: the bit of the word being waited on
16362306a36Sopenharmony_ci * @mode: the task state to sleep in
16462306a36Sopenharmony_ci *
16562306a36Sopenharmony_ci * There is a standard hashed waitqueue table for generic use. This
16662306a36Sopenharmony_ci * is the part of the hashtable's accessor API that waits on a bit
16762306a36Sopenharmony_ci * when one intends to set it, for instance, trying to lock bitflags.
16862306a36Sopenharmony_ci * For instance, if one were to have waiters trying to set bitflag
16962306a36Sopenharmony_ci * and waiting for it to clear before setting it, one would call
17062306a36Sopenharmony_ci * wait_on_bit() in threads waiting to be able to set the bit.
17162306a36Sopenharmony_ci * One uses wait_on_bit_lock() where one is waiting for the bit to
17262306a36Sopenharmony_ci * clear with the intention of setting it, and when done, clearing it.
17362306a36Sopenharmony_ci *
17462306a36Sopenharmony_ci * Returns zero if the bit was (eventually) found to be clear and was
17562306a36Sopenharmony_ci * set.  Returns non-zero if a signal was delivered to the process and
17662306a36Sopenharmony_ci * the @mode allows that signal to wake the process.
17762306a36Sopenharmony_ci */
17862306a36Sopenharmony_cistatic inline int
17962306a36Sopenharmony_ciwait_on_bit_lock(unsigned long *word, int bit, unsigned mode)
18062306a36Sopenharmony_ci{
18162306a36Sopenharmony_ci	might_sleep();
18262306a36Sopenharmony_ci	if (!test_and_set_bit(bit, word))
18362306a36Sopenharmony_ci		return 0;
18462306a36Sopenharmony_ci	return out_of_line_wait_on_bit_lock(word, bit, bit_wait, mode);
18562306a36Sopenharmony_ci}
18662306a36Sopenharmony_ci
18762306a36Sopenharmony_ci/**
18862306a36Sopenharmony_ci * wait_on_bit_lock_io - wait for a bit to be cleared, when wanting to set it
18962306a36Sopenharmony_ci * @word: the word being waited on, a kernel virtual address
19062306a36Sopenharmony_ci * @bit: the bit of the word being waited on
19162306a36Sopenharmony_ci * @mode: the task state to sleep in
19262306a36Sopenharmony_ci *
19362306a36Sopenharmony_ci * Use the standard hashed waitqueue table to wait for a bit
19462306a36Sopenharmony_ci * to be cleared and then to atomically set it.  This is similar
19562306a36Sopenharmony_ci * to wait_on_bit(), but calls io_schedule() instead of schedule()
19662306a36Sopenharmony_ci * for the actual waiting.
19762306a36Sopenharmony_ci *
19862306a36Sopenharmony_ci * Returns zero if the bit was (eventually) found to be clear and was
19962306a36Sopenharmony_ci * set.  Returns non-zero if a signal was delivered to the process and
20062306a36Sopenharmony_ci * the @mode allows that signal to wake the process.
20162306a36Sopenharmony_ci */
20262306a36Sopenharmony_cistatic inline int
20362306a36Sopenharmony_ciwait_on_bit_lock_io(unsigned long *word, int bit, unsigned mode)
20462306a36Sopenharmony_ci{
20562306a36Sopenharmony_ci	might_sleep();
20662306a36Sopenharmony_ci	if (!test_and_set_bit(bit, word))
20762306a36Sopenharmony_ci		return 0;
20862306a36Sopenharmony_ci	return out_of_line_wait_on_bit_lock(word, bit, bit_wait_io, mode);
20962306a36Sopenharmony_ci}
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci/**
21262306a36Sopenharmony_ci * wait_on_bit_lock_action - wait for a bit to be cleared, when wanting to set it
21362306a36Sopenharmony_ci * @word: the word being waited on, a kernel virtual address
21462306a36Sopenharmony_ci * @bit: the bit of the word being waited on
21562306a36Sopenharmony_ci * @action: the function used to sleep, which may take special actions
21662306a36Sopenharmony_ci * @mode: the task state to sleep in
21762306a36Sopenharmony_ci *
21862306a36Sopenharmony_ci * Use the standard hashed waitqueue table to wait for a bit
21962306a36Sopenharmony_ci * to be cleared and then to set it, and allow the waiting action
22062306a36Sopenharmony_ci * to be specified.
22162306a36Sopenharmony_ci * This is like wait_on_bit() but allows fine control of how the waiting
22262306a36Sopenharmony_ci * is done.
22362306a36Sopenharmony_ci *
22462306a36Sopenharmony_ci * Returns zero if the bit was (eventually) found to be clear and was
22562306a36Sopenharmony_ci * set.  Returns non-zero if a signal was delivered to the process and
22662306a36Sopenharmony_ci * the @mode allows that signal to wake the process.
22762306a36Sopenharmony_ci */
22862306a36Sopenharmony_cistatic inline int
22962306a36Sopenharmony_ciwait_on_bit_lock_action(unsigned long *word, int bit, wait_bit_action_f *action,
23062306a36Sopenharmony_ci			unsigned mode)
23162306a36Sopenharmony_ci{
23262306a36Sopenharmony_ci	might_sleep();
23362306a36Sopenharmony_ci	if (!test_and_set_bit(bit, word))
23462306a36Sopenharmony_ci		return 0;
23562306a36Sopenharmony_ci	return out_of_line_wait_on_bit_lock(word, bit, action, mode);
23662306a36Sopenharmony_ci}
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_ciextern void init_wait_var_entry(struct wait_bit_queue_entry *wbq_entry, void *var, int flags);
23962306a36Sopenharmony_ciextern void wake_up_var(void *var);
24062306a36Sopenharmony_ciextern wait_queue_head_t *__var_waitqueue(void *p);
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ci#define ___wait_var_event(var, condition, state, exclusive, ret, cmd)	\
24362306a36Sopenharmony_ci({									\
24462306a36Sopenharmony_ci	__label__ __out;						\
24562306a36Sopenharmony_ci	struct wait_queue_head *__wq_head = __var_waitqueue(var);	\
24662306a36Sopenharmony_ci	struct wait_bit_queue_entry __wbq_entry;			\
24762306a36Sopenharmony_ci	long __ret = ret; /* explicit shadow */				\
24862306a36Sopenharmony_ci									\
24962306a36Sopenharmony_ci	init_wait_var_entry(&__wbq_entry, var,				\
25062306a36Sopenharmony_ci			    exclusive ? WQ_FLAG_EXCLUSIVE : 0);		\
25162306a36Sopenharmony_ci	for (;;) {							\
25262306a36Sopenharmony_ci		long __int = prepare_to_wait_event(__wq_head,		\
25362306a36Sopenharmony_ci						   &__wbq_entry.wq_entry, \
25462306a36Sopenharmony_ci						   state);		\
25562306a36Sopenharmony_ci		if (condition)						\
25662306a36Sopenharmony_ci			break;						\
25762306a36Sopenharmony_ci									\
25862306a36Sopenharmony_ci		if (___wait_is_interruptible(state) && __int) {		\
25962306a36Sopenharmony_ci			__ret = __int;					\
26062306a36Sopenharmony_ci			goto __out;					\
26162306a36Sopenharmony_ci		}							\
26262306a36Sopenharmony_ci									\
26362306a36Sopenharmony_ci		cmd;							\
26462306a36Sopenharmony_ci	}								\
26562306a36Sopenharmony_ci	finish_wait(__wq_head, &__wbq_entry.wq_entry);			\
26662306a36Sopenharmony_ci__out:	__ret;								\
26762306a36Sopenharmony_ci})
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_ci#define __wait_var_event(var, condition)				\
27062306a36Sopenharmony_ci	___wait_var_event(var, condition, TASK_UNINTERRUPTIBLE, 0, 0,	\
27162306a36Sopenharmony_ci			  schedule())
27262306a36Sopenharmony_ci
27362306a36Sopenharmony_ci#define wait_var_event(var, condition)					\
27462306a36Sopenharmony_cido {									\
27562306a36Sopenharmony_ci	might_sleep();							\
27662306a36Sopenharmony_ci	if (condition)							\
27762306a36Sopenharmony_ci		break;							\
27862306a36Sopenharmony_ci	__wait_var_event(var, condition);				\
27962306a36Sopenharmony_ci} while (0)
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ci#define __wait_var_event_killable(var, condition)			\
28262306a36Sopenharmony_ci	___wait_var_event(var, condition, TASK_KILLABLE, 0, 0,		\
28362306a36Sopenharmony_ci			  schedule())
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_ci#define wait_var_event_killable(var, condition)				\
28662306a36Sopenharmony_ci({									\
28762306a36Sopenharmony_ci	int __ret = 0;							\
28862306a36Sopenharmony_ci	might_sleep();							\
28962306a36Sopenharmony_ci	if (!(condition))						\
29062306a36Sopenharmony_ci		__ret = __wait_var_event_killable(var, condition);	\
29162306a36Sopenharmony_ci	__ret;								\
29262306a36Sopenharmony_ci})
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_ci#define __wait_var_event_timeout(var, condition, timeout)		\
29562306a36Sopenharmony_ci	___wait_var_event(var, ___wait_cond_timeout(condition),		\
29662306a36Sopenharmony_ci			  TASK_UNINTERRUPTIBLE, 0, timeout,		\
29762306a36Sopenharmony_ci			  __ret = schedule_timeout(__ret))
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci#define wait_var_event_timeout(var, condition, timeout)			\
30062306a36Sopenharmony_ci({									\
30162306a36Sopenharmony_ci	long __ret = timeout;						\
30262306a36Sopenharmony_ci	might_sleep();							\
30362306a36Sopenharmony_ci	if (!___wait_cond_timeout(condition))				\
30462306a36Sopenharmony_ci		__ret = __wait_var_event_timeout(var, condition, timeout); \
30562306a36Sopenharmony_ci	__ret;								\
30662306a36Sopenharmony_ci})
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ci#define __wait_var_event_interruptible(var, condition)			\
30962306a36Sopenharmony_ci	___wait_var_event(var, condition, TASK_INTERRUPTIBLE, 0, 0,	\
31062306a36Sopenharmony_ci			  schedule())
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_ci#define wait_var_event_interruptible(var, condition)			\
31362306a36Sopenharmony_ci({									\
31462306a36Sopenharmony_ci	int __ret = 0;							\
31562306a36Sopenharmony_ci	might_sleep();							\
31662306a36Sopenharmony_ci	if (!(condition))						\
31762306a36Sopenharmony_ci		__ret = __wait_var_event_interruptible(var, condition);	\
31862306a36Sopenharmony_ci	__ret;								\
31962306a36Sopenharmony_ci})
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_ci/**
32262306a36Sopenharmony_ci * clear_and_wake_up_bit - clear a bit and wake up anyone waiting on that bit
32362306a36Sopenharmony_ci *
32462306a36Sopenharmony_ci * @bit: the bit of the word being waited on
32562306a36Sopenharmony_ci * @word: the word being waited on, a kernel virtual address
32662306a36Sopenharmony_ci *
32762306a36Sopenharmony_ci * You can use this helper if bitflags are manipulated atomically rather than
32862306a36Sopenharmony_ci * non-atomically under a lock.
32962306a36Sopenharmony_ci */
33062306a36Sopenharmony_cistatic inline void clear_and_wake_up_bit(int bit, void *word)
33162306a36Sopenharmony_ci{
33262306a36Sopenharmony_ci	clear_bit_unlock(bit, word);
33362306a36Sopenharmony_ci	/* See wake_up_bit() for which memory barrier you need to use. */
33462306a36Sopenharmony_ci	smp_mb__after_atomic();
33562306a36Sopenharmony_ci	wake_up_bit(word, bit);
33662306a36Sopenharmony_ci}
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_ci#endif /* _LINUX_WAIT_BIT_H */
339