Skip to content

Commit 00c0c59

Browse files
committed
sched: Document wait_var_event() family of functions and wake_up_var()
JIRA: https://issues.redhat.com/browse/RHEL-117497 commit bf39882 Author: NeilBrown <neilb@suse.de> Date: Wed Sep 25 15:31:40 2024 +1000 sched: Document wait_var_event() family of functions and wake_up_var() wake_up_var(), wait_var_event() and related interfaces are not documented but have important ordering requirements. This patch adds documentation and makes these requirements explicit. The return values for those wait_var_event_* functions which return a value are documented. Note that these are, perhaps surprisingly, sometimes different from comparable wait_on_bit() functions. Signed-off-by: NeilBrown <neilb@suse.de> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/r/20240925053405.3960701-4-neilb@suse.de Signed-off-by: Benjamin Coddington <bcodding@redhat.com>
1 parent 99ea334 commit 00c0c59

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed

include/linux/wait_bit.h

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,22 @@ __out: __ret; \
281281
___wait_var_event(var, condition, TASK_UNINTERRUPTIBLE, 0, 0, \
282282
schedule())
283283

284+
/**
285+
* wait_var_event - wait for a variable to be updated and notified
286+
* @var: the address of variable being waited on
287+
* @condition: the condition to wait for
288+
*
289+
* Wait for a @condition to be true, only re-checking when a wake up is
290+
* received for the given @var (an arbitrary kernel address which need
291+
* not be directly related to the given condition, but usually is).
292+
*
293+
* The process will wait on a waitqueue selected by hash from a shared
294+
* pool. It will only be woken on a wake_up for the given address.
295+
*
296+
* The condition should normally use smp_load_acquire() or a similarly
297+
* ordered access to ensure that any changes to memory made before the
298+
* condition became true will be visible after the wait completes.
299+
*/
284300
#define wait_var_event(var, condition) \
285301
do { \
286302
might_sleep(); \
@@ -293,6 +309,24 @@ do { \
293309
___wait_var_event(var, condition, TASK_KILLABLE, 0, 0, \
294310
schedule())
295311

312+
/**
313+
* wait_var_event_killable - wait for a variable to be updated and notified
314+
* @var: the address of variable being waited on
315+
* @condition: the condition to wait for
316+
*
317+
* Wait for a @condition to be true or a fatal signal to be received,
318+
* only re-checking the condition when a wake up is received for the given
319+
* @var (an arbitrary kernel address which need not be directly related
320+
* to the given condition, but usually is).
321+
*
322+
* This is similar to wait_var_event() but returns a value which is
323+
* 0 if the condition became true, or %-ERESTARTSYS if a fatal signal
324+
* was received.
325+
*
326+
* The condition should normally use smp_load_acquire() or a similarly
327+
* ordered access to ensure that any changes to memory made before the
328+
* condition became true will be visible after the wait completes.
329+
*/
296330
#define wait_var_event_killable(var, condition) \
297331
({ \
298332
int __ret = 0; \
@@ -307,6 +341,26 @@ do { \
307341
TASK_UNINTERRUPTIBLE, 0, timeout, \
308342
__ret = schedule_timeout(__ret))
309343

344+
/**
345+
* wait_var_event_timeout - wait for a variable to be updated or a timeout to expire
346+
* @var: the address of variable being waited on
347+
* @condition: the condition to wait for
348+
* @timeout: maximum time to wait in jiffies
349+
*
350+
* Wait for a @condition to be true or a timeout to expire, only
351+
* re-checking the condition when a wake up is received for the given
352+
* @var (an arbitrary kernel address which need not be directly related
353+
* to the given condition, but usually is).
354+
*
355+
* This is similar to wait_var_event() but returns a value which is 0 if
356+
* the timeout expired and the condition was still false, or the
357+
* remaining time left in the timeout (but at least 1) if the condition
358+
* was found to be true.
359+
*
360+
* The condition should normally use smp_load_acquire() or a similarly
361+
* ordered access to ensure that any changes to memory made before the
362+
* condition became true will be visible after the wait completes.
363+
*/
310364
#define wait_var_event_timeout(var, condition, timeout) \
311365
({ \
312366
long __ret = timeout; \
@@ -320,6 +374,23 @@ do { \
320374
___wait_var_event(var, condition, TASK_INTERRUPTIBLE, 0, 0, \
321375
schedule())
322376

377+
/**
378+
* wait_var_event_killable - wait for a variable to be updated and notified
379+
* @var: the address of variable being waited on
380+
* @condition: the condition to wait for
381+
*
382+
* Wait for a @condition to be true or a signal to be received, only
383+
* re-checking the condition when a wake up is received for the given
384+
* @var (an arbitrary kernel address which need not be directly related
385+
* to the given condition, but usually is).
386+
*
387+
* This is similar to wait_var_event() but returns a value which is 0 if
388+
* the condition became true, or %-ERESTARTSYS if a signal was received.
389+
*
390+
* The condition should normally use smp_load_acquire() or a similarly
391+
* ordered access to ensure that any changes to memory made before the
392+
* condition became true will be visible after the wait completes.
393+
*/
323394
#define wait_var_event_interruptible(var, condition) \
324395
({ \
325396
int __ret = 0; \

kernel/sched/wait_bit.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,36 @@ void init_wait_var_entry(struct wait_bit_queue_entry *wbq_entry, void *var, int
196196
}
197197
EXPORT_SYMBOL(init_wait_var_entry);
198198

199+
/**
200+
* wake_up_var - wake up waiters on a variable (kernel address)
201+
* @var: the address of the variable being waited on
202+
*
203+
* Wake up any process waiting in wait_var_event() or similar for the
204+
* given variable to change. wait_var_event() can be waiting for an
205+
* arbitrary condition to be true and associates that condition with an
206+
* address. Calling wake_up_var() suggests that the condition has been
207+
* made true, but does not strictly require the condtion to use the
208+
* address given.
209+
*
210+
* The wake-up is sent to tasks in a waitqueue selected by hash from a
211+
* shared pool. Only those tasks on that queue which have requested
212+
* wake_up on this specific address will be woken.
213+
*
214+
* In order for this to function properly there must be a full memory
215+
* barrier after the variable is updated (or more accurately, after the
216+
* condition waited on has been made to be true) and before this function
217+
* is called. If the variable was updated atomically, such as a by
218+
* atomic_dec() then smb_mb__after_atomic() can be used. If the
219+
* variable was updated by a fully ordered operation such as
220+
* atomic_dec_and_test() then no extra barrier is required. Otherwise
221+
* smb_mb() is needed.
222+
*
223+
* Normally the variable should be updated (the condition should be made
224+
* to be true) by an operation with RELEASE semantics such as
225+
* smp_store_release() so that any changes to memory made before the
226+
* variable was updated are guaranteed to be visible after the matching
227+
* wait_var_event() completes.
228+
*/
199229
void wake_up_var(void *var)
200230
{
201231
__wake_up_bit(__var_waitqueue(var), var, -1);

0 commit comments

Comments
 (0)