xref: /linux-6.15/include/linux/closure.h (revision 04b670de)
18c8d2d96SKent Overstreet /* SPDX-License-Identifier: GPL-2.0 */
28c8d2d96SKent Overstreet #ifndef _LINUX_CLOSURE_H
38c8d2d96SKent Overstreet #define _LINUX_CLOSURE_H
48c8d2d96SKent Overstreet 
58c8d2d96SKent Overstreet #include <linux/llist.h>
68c8d2d96SKent Overstreet #include <linux/sched.h>
78c8d2d96SKent Overstreet #include <linux/sched/task_stack.h>
88c8d2d96SKent Overstreet #include <linux/workqueue.h>
98c8d2d96SKent Overstreet 
108c8d2d96SKent Overstreet /*
118c8d2d96SKent Overstreet  * Closure is perhaps the most overused and abused term in computer science, but
128c8d2d96SKent Overstreet  * since I've been unable to come up with anything better you're stuck with it
138c8d2d96SKent Overstreet  * again.
148c8d2d96SKent Overstreet  *
158c8d2d96SKent Overstreet  * What are closures?
168c8d2d96SKent Overstreet  *
178c8d2d96SKent Overstreet  * They embed a refcount. The basic idea is they count "things that are in
188c8d2d96SKent Overstreet  * progress" - in flight bios, some other thread that's doing something else -
198c8d2d96SKent Overstreet  * anything you might want to wait on.
208c8d2d96SKent Overstreet  *
218c8d2d96SKent Overstreet  * The refcount may be manipulated with closure_get() and closure_put().
228c8d2d96SKent Overstreet  * closure_put() is where many of the interesting things happen, when it causes
238c8d2d96SKent Overstreet  * the refcount to go to 0.
248c8d2d96SKent Overstreet  *
258c8d2d96SKent Overstreet  * Closures can be used to wait on things both synchronously and asynchronously,
268c8d2d96SKent Overstreet  * and synchronous and asynchronous use can be mixed without restriction. To
278c8d2d96SKent Overstreet  * wait synchronously, use closure_sync() - you will sleep until your closure's
288c8d2d96SKent Overstreet  * refcount hits 1.
298c8d2d96SKent Overstreet  *
308c8d2d96SKent Overstreet  * To wait asynchronously, use
318c8d2d96SKent Overstreet  *   continue_at(cl, next_function, workqueue);
328c8d2d96SKent Overstreet  *
338c8d2d96SKent Overstreet  * passing it, as you might expect, the function to run when nothing is pending
348c8d2d96SKent Overstreet  * and the workqueue to run that function out of.
358c8d2d96SKent Overstreet  *
368c8d2d96SKent Overstreet  * continue_at() also, critically, requires a 'return' immediately following the
378c8d2d96SKent Overstreet  * location where this macro is referenced, to return to the calling function.
388c8d2d96SKent Overstreet  * There's good reason for this.
398c8d2d96SKent Overstreet  *
408c8d2d96SKent Overstreet  * To use safely closures asynchronously, they must always have a refcount while
418c8d2d96SKent Overstreet  * they are running owned by the thread that is running them. Otherwise, suppose
428c8d2d96SKent Overstreet  * you submit some bios and wish to have a function run when they all complete:
438c8d2d96SKent Overstreet  *
448c8d2d96SKent Overstreet  * foo_endio(struct bio *bio)
458c8d2d96SKent Overstreet  * {
468c8d2d96SKent Overstreet  *	closure_put(cl);
478c8d2d96SKent Overstreet  * }
488c8d2d96SKent Overstreet  *
498c8d2d96SKent Overstreet  * closure_init(cl);
508c8d2d96SKent Overstreet  *
518c8d2d96SKent Overstreet  * do_stuff();
528c8d2d96SKent Overstreet  * closure_get(cl);
538c8d2d96SKent Overstreet  * bio1->bi_endio = foo_endio;
548c8d2d96SKent Overstreet  * bio_submit(bio1);
558c8d2d96SKent Overstreet  *
568c8d2d96SKent Overstreet  * do_more_stuff();
578c8d2d96SKent Overstreet  * closure_get(cl);
588c8d2d96SKent Overstreet  * bio2->bi_endio = foo_endio;
598c8d2d96SKent Overstreet  * bio_submit(bio2);
608c8d2d96SKent Overstreet  *
618c8d2d96SKent Overstreet  * continue_at(cl, complete_some_read, system_wq);
628c8d2d96SKent Overstreet  *
638c8d2d96SKent Overstreet  * If closure's refcount started at 0, complete_some_read() could run before the
648c8d2d96SKent Overstreet  * second bio was submitted - which is almost always not what you want! More
658c8d2d96SKent Overstreet  * importantly, it wouldn't be possible to say whether the original thread or
668c8d2d96SKent Overstreet  * complete_some_read()'s thread owned the closure - and whatever state it was
678c8d2d96SKent Overstreet  * associated with!
688c8d2d96SKent Overstreet  *
698c8d2d96SKent Overstreet  * So, closure_init() initializes a closure's refcount to 1 - and when a
708c8d2d96SKent Overstreet  * closure_fn is run, the refcount will be reset to 1 first.
718c8d2d96SKent Overstreet  *
728c8d2d96SKent Overstreet  * Then, the rule is - if you got the refcount with closure_get(), release it
738c8d2d96SKent Overstreet  * with closure_put() (i.e, in a bio->bi_endio function). If you have a refcount
748c8d2d96SKent Overstreet  * on a closure because you called closure_init() or you were run out of a
758c8d2d96SKent Overstreet  * closure - _always_ use continue_at(). Doing so consistently will help
768c8d2d96SKent Overstreet  * eliminate an entire class of particularly pernicious races.
778c8d2d96SKent Overstreet  *
788c8d2d96SKent Overstreet  * Lastly, you might have a wait list dedicated to a specific event, and have no
798c8d2d96SKent Overstreet  * need for specifying the condition - you just want to wait until someone runs
808c8d2d96SKent Overstreet  * closure_wake_up() on the appropriate wait list. In that case, just use
818c8d2d96SKent Overstreet  * closure_wait(). It will return either true or false, depending on whether the
828c8d2d96SKent Overstreet  * closure was already on a wait list or not - a closure can only be on one wait
838c8d2d96SKent Overstreet  * list at a time.
848c8d2d96SKent Overstreet  *
858c8d2d96SKent Overstreet  * Parents:
868c8d2d96SKent Overstreet  *
878c8d2d96SKent Overstreet  * closure_init() takes two arguments - it takes the closure to initialize, and
888c8d2d96SKent Overstreet  * a (possibly null) parent.
898c8d2d96SKent Overstreet  *
908c8d2d96SKent Overstreet  * If parent is non null, the new closure will have a refcount for its lifetime;
918c8d2d96SKent Overstreet  * a closure is considered to be "finished" when its refcount hits 0 and the
928c8d2d96SKent Overstreet  * function to run is null. Hence
938c8d2d96SKent Overstreet  *
948c8d2d96SKent Overstreet  * continue_at(cl, NULL, NULL);
958c8d2d96SKent Overstreet  *
968c8d2d96SKent Overstreet  * returns up the (spaghetti) stack of closures, precisely like normal return
978c8d2d96SKent Overstreet  * returns up the C stack. continue_at() with non null fn is better thought of
988c8d2d96SKent Overstreet  * as doing a tail call.
998c8d2d96SKent Overstreet  *
1008c8d2d96SKent Overstreet  * All this implies that a closure should typically be embedded in a particular
1018c8d2d96SKent Overstreet  * struct (which its refcount will normally control the lifetime of), and that
1028c8d2d96SKent Overstreet  * struct can very much be thought of as a stack frame.
1038c8d2d96SKent Overstreet  */
1048c8d2d96SKent Overstreet 
1058c8d2d96SKent Overstreet struct closure;
1068c8d2d96SKent Overstreet struct closure_syncer;
107d4e3b928SKent Overstreet typedef void (closure_fn) (struct work_struct *);
1088c8d2d96SKent Overstreet extern struct dentry *bcache_debug;
1098c8d2d96SKent Overstreet 
1108c8d2d96SKent Overstreet struct closure_waitlist {
1118c8d2d96SKent Overstreet 	struct llist_head	list;
1128c8d2d96SKent Overstreet };
1138c8d2d96SKent Overstreet 
1148c8d2d96SKent Overstreet enum closure_state {
1158c8d2d96SKent Overstreet 	/*
1168c8d2d96SKent Overstreet 	 * CLOSURE_WAITING: Set iff the closure is on a waitlist. Must be set by
1178c8d2d96SKent Overstreet 	 * the thread that owns the closure, and cleared by the thread that's
1188c8d2d96SKent Overstreet 	 * waking up the closure.
1198c8d2d96SKent Overstreet 	 *
1208c8d2d96SKent Overstreet 	 * The rest are for debugging and don't affect behaviour:
1218c8d2d96SKent Overstreet 	 *
1228c8d2d96SKent Overstreet 	 * CLOSURE_RUNNING: Set when a closure is running (i.e. by
1238c8d2d96SKent Overstreet 	 * closure_init() and when closure_put() runs then next function), and
1248c8d2d96SKent Overstreet 	 * must be cleared before remaining hits 0. Primarily to help guard
1258c8d2d96SKent Overstreet 	 * against incorrect usage and accidentally transferring references.
1268c8d2d96SKent Overstreet 	 * continue_at() and closure_return() clear it for you, if you're doing
1278c8d2d96SKent Overstreet 	 * something unusual you can use closure_set_dead() which also helps
1288c8d2d96SKent Overstreet 	 * annotate where references are being transferred.
1298c8d2d96SKent Overstreet 	 */
1308c8d2d96SKent Overstreet 
1318c8d2d96SKent Overstreet 	CLOSURE_BITS_START	= (1U << 26),
1328c8d2d96SKent Overstreet 	CLOSURE_DESTRUCTOR	= (1U << 26),
1338c8d2d96SKent Overstreet 	CLOSURE_WAITING		= (1U << 28),
1348c8d2d96SKent Overstreet 	CLOSURE_RUNNING		= (1U << 30),
1358c8d2d96SKent Overstreet };
1368c8d2d96SKent Overstreet 
1378c8d2d96SKent Overstreet #define CLOSURE_GUARD_MASK					\
1388c8d2d96SKent Overstreet 	((CLOSURE_DESTRUCTOR|CLOSURE_WAITING|CLOSURE_RUNNING) << 1)
1398c8d2d96SKent Overstreet 
1408c8d2d96SKent Overstreet #define CLOSURE_REMAINING_MASK		(CLOSURE_BITS_START - 1)
1418c8d2d96SKent Overstreet #define CLOSURE_REMAINING_INITIALIZER	(1|CLOSURE_RUNNING)
1428c8d2d96SKent Overstreet 
1438c8d2d96SKent Overstreet struct closure {
1448c8d2d96SKent Overstreet 	union {
1458c8d2d96SKent Overstreet 		struct {
1468c8d2d96SKent Overstreet 			struct workqueue_struct *wq;
1478c8d2d96SKent Overstreet 			struct closure_syncer	*s;
1488c8d2d96SKent Overstreet 			struct llist_node	list;
1498c8d2d96SKent Overstreet 			closure_fn		*fn;
1508c8d2d96SKent Overstreet 		};
1518c8d2d96SKent Overstreet 		struct work_struct	work;
1528c8d2d96SKent Overstreet 	};
1538c8d2d96SKent Overstreet 
1548c8d2d96SKent Overstreet 	struct closure		*parent;
1558c8d2d96SKent Overstreet 
1568c8d2d96SKent Overstreet 	atomic_t		remaining;
157ee526b88SKent Overstreet 	bool			closure_get_happened;
1588c8d2d96SKent Overstreet 
1598c8d2d96SKent Overstreet #ifdef CONFIG_DEBUG_CLOSURES
1608c8d2d96SKent Overstreet #define CLOSURE_MAGIC_DEAD	0xc054dead
1618c8d2d96SKent Overstreet #define CLOSURE_MAGIC_ALIVE	0xc054a11e
16229f1c1aeSKent Overstreet #define CLOSURE_MAGIC_STACK	0xc05451cc
1638c8d2d96SKent Overstreet 
1648c8d2d96SKent Overstreet 	unsigned int		magic;
1658c8d2d96SKent Overstreet 	struct list_head	all;
1668c8d2d96SKent Overstreet 	unsigned long		ip;
1678c8d2d96SKent Overstreet 	unsigned long		waiting_on;
1688c8d2d96SKent Overstreet #endif
1698c8d2d96SKent Overstreet };
1708c8d2d96SKent Overstreet 
1718c8d2d96SKent Overstreet void closure_sub(struct closure *cl, int v);
1728c8d2d96SKent Overstreet void closure_put(struct closure *cl);
1738c8d2d96SKent Overstreet void __closure_wake_up(struct closure_waitlist *list);
1748c8d2d96SKent Overstreet bool closure_wait(struct closure_waitlist *list, struct closure *cl);
1758c8d2d96SKent Overstreet void __closure_sync(struct closure *cl);
1768c8d2d96SKent Overstreet 
closure_nr_remaining(struct closure * cl)17748b79357SKent Overstreet static inline unsigned closure_nr_remaining(struct closure *cl)
17848b79357SKent Overstreet {
17948b79357SKent Overstreet 	return atomic_read(&cl->remaining) & CLOSURE_REMAINING_MASK;
18048b79357SKent Overstreet }
18148b79357SKent Overstreet 
1828c8d2d96SKent Overstreet /**
1838c8d2d96SKent Overstreet  * closure_sync - sleep until a closure a closure has nothing left to wait on
1848c8d2d96SKent Overstreet  *
1858c8d2d96SKent Overstreet  * Sleeps until the refcount hits 1 - the thread that's running the closure owns
1868c8d2d96SKent Overstreet  * the last refcount.
1878c8d2d96SKent Overstreet  */
closure_sync(struct closure * cl)1888c8d2d96SKent Overstreet static inline void closure_sync(struct closure *cl)
1898c8d2d96SKent Overstreet {
190ee526b88SKent Overstreet #ifdef CONFIG_DEBUG_CLOSURES
191ee526b88SKent Overstreet 	BUG_ON(closure_nr_remaining(cl) != 1 && !cl->closure_get_happened);
192ee526b88SKent Overstreet #endif
193ee526b88SKent Overstreet 
194ee526b88SKent Overstreet 	if (cl->closure_get_happened)
1958c8d2d96SKent Overstreet 		__closure_sync(cl);
1968c8d2d96SKent Overstreet }
1978c8d2d96SKent Overstreet 
1984c5b7294SKent Overstreet int __closure_sync_timeout(struct closure *cl, unsigned long timeout);
1994c5b7294SKent Overstreet 
closure_sync_timeout(struct closure * cl,unsigned long timeout)2004c5b7294SKent Overstreet static inline int closure_sync_timeout(struct closure *cl, unsigned long timeout)
2014c5b7294SKent Overstreet {
2024c5b7294SKent Overstreet #ifdef CONFIG_DEBUG_CLOSURES
2034c5b7294SKent Overstreet 	BUG_ON(closure_nr_remaining(cl) != 1 && !cl->closure_get_happened);
2044c5b7294SKent Overstreet #endif
2054c5b7294SKent Overstreet 	return cl->closure_get_happened
2064c5b7294SKent Overstreet 		? __closure_sync_timeout(cl, timeout)
2074c5b7294SKent Overstreet 		: 0;
2084c5b7294SKent Overstreet }
2094c5b7294SKent Overstreet 
2108c8d2d96SKent Overstreet #ifdef CONFIG_DEBUG_CLOSURES
2118c8d2d96SKent Overstreet 
2128c8d2d96SKent Overstreet void closure_debug_create(struct closure *cl);
2138c8d2d96SKent Overstreet void closure_debug_destroy(struct closure *cl);
2148c8d2d96SKent Overstreet 
2158c8d2d96SKent Overstreet #else
2168c8d2d96SKent Overstreet 
closure_debug_create(struct closure * cl)2178c8d2d96SKent Overstreet static inline void closure_debug_create(struct closure *cl) {}
closure_debug_destroy(struct closure * cl)2188c8d2d96SKent Overstreet static inline void closure_debug_destroy(struct closure *cl) {}
2198c8d2d96SKent Overstreet 
2208c8d2d96SKent Overstreet #endif
2218c8d2d96SKent Overstreet 
closure_set_ip(struct closure * cl)2228c8d2d96SKent Overstreet static inline void closure_set_ip(struct closure *cl)
2238c8d2d96SKent Overstreet {
2248c8d2d96SKent Overstreet #ifdef CONFIG_DEBUG_CLOSURES
2258c8d2d96SKent Overstreet 	cl->ip = _THIS_IP_;
2268c8d2d96SKent Overstreet #endif
2278c8d2d96SKent Overstreet }
2288c8d2d96SKent Overstreet 
closure_set_ret_ip(struct closure * cl)2298c8d2d96SKent Overstreet static inline void closure_set_ret_ip(struct closure *cl)
2308c8d2d96SKent Overstreet {
2318c8d2d96SKent Overstreet #ifdef CONFIG_DEBUG_CLOSURES
2328c8d2d96SKent Overstreet 	cl->ip = _RET_IP_;
2338c8d2d96SKent Overstreet #endif
2348c8d2d96SKent Overstreet }
2358c8d2d96SKent Overstreet 
closure_set_waiting(struct closure * cl,unsigned long f)2368c8d2d96SKent Overstreet static inline void closure_set_waiting(struct closure *cl, unsigned long f)
2378c8d2d96SKent Overstreet {
2388c8d2d96SKent Overstreet #ifdef CONFIG_DEBUG_CLOSURES
2398c8d2d96SKent Overstreet 	cl->waiting_on = f;
2408c8d2d96SKent Overstreet #endif
2418c8d2d96SKent Overstreet }
2428c8d2d96SKent Overstreet 
closure_set_stopped(struct closure * cl)2438c8d2d96SKent Overstreet static inline void closure_set_stopped(struct closure *cl)
2448c8d2d96SKent Overstreet {
2458c8d2d96SKent Overstreet 	atomic_sub(CLOSURE_RUNNING, &cl->remaining);
2468c8d2d96SKent Overstreet }
2478c8d2d96SKent Overstreet 
set_closure_fn(struct closure * cl,closure_fn * fn,struct workqueue_struct * wq)2488c8d2d96SKent Overstreet static inline void set_closure_fn(struct closure *cl, closure_fn *fn,
2498c8d2d96SKent Overstreet 				  struct workqueue_struct *wq)
2508c8d2d96SKent Overstreet {
2518c8d2d96SKent Overstreet 	closure_set_ip(cl);
2528c8d2d96SKent Overstreet 	cl->fn = fn;
2538c8d2d96SKent Overstreet 	cl->wq = wq;
2548c8d2d96SKent Overstreet }
2558c8d2d96SKent Overstreet 
closure_queue(struct closure * cl)2568c8d2d96SKent Overstreet static inline void closure_queue(struct closure *cl)
2578c8d2d96SKent Overstreet {
2588c8d2d96SKent Overstreet 	struct workqueue_struct *wq = cl->wq;
2598c8d2d96SKent Overstreet 	/**
2608c8d2d96SKent Overstreet 	 * Changes made to closure, work_struct, or a couple of other structs
2618c8d2d96SKent Overstreet 	 * may cause work.func not pointing to the right location.
2628c8d2d96SKent Overstreet 	 */
2638c8d2d96SKent Overstreet 	BUILD_BUG_ON(offsetof(struct closure, fn)
2648c8d2d96SKent Overstreet 		     != offsetof(struct work_struct, func));
2658c8d2d96SKent Overstreet 
2668c8d2d96SKent Overstreet 	if (wq) {
2678c8d2d96SKent Overstreet 		INIT_WORK(&cl->work, cl->work.func);
2688c8d2d96SKent Overstreet 		BUG_ON(!queue_work(wq, &cl->work));
2698c8d2d96SKent Overstreet 	} else
270d4e3b928SKent Overstreet 		cl->fn(&cl->work);
2718c8d2d96SKent Overstreet }
2728c8d2d96SKent Overstreet 
2738c8d2d96SKent Overstreet /**
2748c8d2d96SKent Overstreet  * closure_get - increment a closure's refcount
2758c8d2d96SKent Overstreet  */
closure_get(struct closure * cl)2768c8d2d96SKent Overstreet static inline void closure_get(struct closure *cl)
2778c8d2d96SKent Overstreet {
278ee526b88SKent Overstreet 	cl->closure_get_happened = true;
279ee526b88SKent Overstreet 
2808c8d2d96SKent Overstreet #ifdef CONFIG_DEBUG_CLOSURES
2818c8d2d96SKent Overstreet 	BUG_ON((atomic_inc_return(&cl->remaining) &
2828c8d2d96SKent Overstreet 		CLOSURE_REMAINING_MASK) <= 1);
2838c8d2d96SKent Overstreet #else
2848c8d2d96SKent Overstreet 	atomic_inc(&cl->remaining);
2858c8d2d96SKent Overstreet #endif
2868c8d2d96SKent Overstreet }
2878c8d2d96SKent Overstreet 
2888c8d2d96SKent Overstreet /**
28906efa5f3SKent Overstreet  * closure_get_not_zero
29006efa5f3SKent Overstreet  */
closure_get_not_zero(struct closure * cl)29106efa5f3SKent Overstreet static inline bool closure_get_not_zero(struct closure *cl)
29206efa5f3SKent Overstreet {
29306efa5f3SKent Overstreet 	unsigned old = atomic_read(&cl->remaining);
29406efa5f3SKent Overstreet 	do {
29506efa5f3SKent Overstreet 		if (!(old & CLOSURE_REMAINING_MASK))
29606efa5f3SKent Overstreet 			return false;
29706efa5f3SKent Overstreet 
29806efa5f3SKent Overstreet 	} while (!atomic_try_cmpxchg_acquire(&cl->remaining, &old, old + 1));
29906efa5f3SKent Overstreet 
30006efa5f3SKent Overstreet 	return true;
30106efa5f3SKent Overstreet }
30206efa5f3SKent Overstreet 
30306efa5f3SKent Overstreet /**
3048c8d2d96SKent Overstreet  * closure_init - Initialize a closure, setting the refcount to 1
3058c8d2d96SKent Overstreet  * @cl:		closure to initialize
3068c8d2d96SKent Overstreet  * @parent:	parent of the new closure. cl will take a refcount on it for its
3078c8d2d96SKent Overstreet  *		lifetime; may be NULL.
3088c8d2d96SKent Overstreet  */
closure_init(struct closure * cl,struct closure * parent)3098c8d2d96SKent Overstreet static inline void closure_init(struct closure *cl, struct closure *parent)
3108c8d2d96SKent Overstreet {
3118c8d2d96SKent Overstreet 	cl->fn = NULL;
3128c8d2d96SKent Overstreet 	cl->parent = parent;
3138c8d2d96SKent Overstreet 	if (parent)
3148c8d2d96SKent Overstreet 		closure_get(parent);
3158c8d2d96SKent Overstreet 
3168c8d2d96SKent Overstreet 	atomic_set(&cl->remaining, CLOSURE_REMAINING_INITIALIZER);
317ee526b88SKent Overstreet 	cl->closure_get_happened = false;
3188c8d2d96SKent Overstreet 
3198c8d2d96SKent Overstreet 	closure_debug_create(cl);
3208c8d2d96SKent Overstreet 	closure_set_ip(cl);
3218c8d2d96SKent Overstreet }
3228c8d2d96SKent Overstreet 
closure_init_stack(struct closure * cl)3238c8d2d96SKent Overstreet static inline void closure_init_stack(struct closure *cl)
3248c8d2d96SKent Overstreet {
3258c8d2d96SKent Overstreet 	memset(cl, 0, sizeof(struct closure));
3268c8d2d96SKent Overstreet 	atomic_set(&cl->remaining, CLOSURE_REMAINING_INITIALIZER);
32729f1c1aeSKent Overstreet #ifdef CONFIG_DEBUG_CLOSURES
32829f1c1aeSKent Overstreet 	cl->magic = CLOSURE_MAGIC_STACK;
32929f1c1aeSKent Overstreet #endif
3308c8d2d96SKent Overstreet }
3318c8d2d96SKent Overstreet 
closure_init_stack_release(struct closure * cl)33206efa5f3SKent Overstreet static inline void closure_init_stack_release(struct closure *cl)
33306efa5f3SKent Overstreet {
33406efa5f3SKent Overstreet 	memset(cl, 0, sizeof(struct closure));
33506efa5f3SKent Overstreet 	atomic_set_release(&cl->remaining, CLOSURE_REMAINING_INITIALIZER);
33629f1c1aeSKent Overstreet #ifdef CONFIG_DEBUG_CLOSURES
33729f1c1aeSKent Overstreet 	cl->magic = CLOSURE_MAGIC_STACK;
33829f1c1aeSKent Overstreet #endif
33906efa5f3SKent Overstreet }
34006efa5f3SKent Overstreet 
3418c8d2d96SKent Overstreet /**
3428c8d2d96SKent Overstreet  * closure_wake_up - wake up all closures on a wait list,
3438c8d2d96SKent Overstreet  *		     with memory barrier
3448c8d2d96SKent Overstreet  */
closure_wake_up(struct closure_waitlist * list)3458c8d2d96SKent Overstreet static inline void closure_wake_up(struct closure_waitlist *list)
3468c8d2d96SKent Overstreet {
3478c8d2d96SKent Overstreet 	/* Memory barrier for the wait list */
3488c8d2d96SKent Overstreet 	smp_mb();
3498c8d2d96SKent Overstreet 	__closure_wake_up(list);
3508c8d2d96SKent Overstreet }
3518c8d2d96SKent Overstreet 
352d4e3b928SKent Overstreet #define CLOSURE_CALLBACK(name)	void name(struct work_struct *ws)
353d4e3b928SKent Overstreet #define closure_type(name, type, member)				\
354d4e3b928SKent Overstreet 	struct closure *cl = container_of(ws, struct closure, work);	\
355d4e3b928SKent Overstreet 	type *name = container_of(cl, type, member)
356d4e3b928SKent Overstreet 
3578c8d2d96SKent Overstreet /**
3588c8d2d96SKent Overstreet  * continue_at - jump to another function with barrier
3598c8d2d96SKent Overstreet  *
3608c8d2d96SKent Overstreet  * After @cl is no longer waiting on anything (i.e. all outstanding refs have
3618c8d2d96SKent Overstreet  * been dropped with closure_put()), it will resume execution at @fn running out
3628c8d2d96SKent Overstreet  * of @wq (or, if @wq is NULL, @fn will be called by closure_put() directly).
3638c8d2d96SKent Overstreet  *
3648c8d2d96SKent Overstreet  * This is because after calling continue_at() you no longer have a ref on @cl,
3658c8d2d96SKent Overstreet  * and whatever @cl owns may be freed out from under you - a running closure fn
3668c8d2d96SKent Overstreet  * has a ref on its own closure which continue_at() drops.
3678c8d2d96SKent Overstreet  *
3688c8d2d96SKent Overstreet  * Note you are expected to immediately return after using this macro.
3698c8d2d96SKent Overstreet  */
3708c8d2d96SKent Overstreet #define continue_at(_cl, _fn, _wq)					\
3718c8d2d96SKent Overstreet do {									\
3728c8d2d96SKent Overstreet 	set_closure_fn(_cl, _fn, _wq);					\
3738c8d2d96SKent Overstreet 	closure_sub(_cl, CLOSURE_RUNNING + 1);				\
3748c8d2d96SKent Overstreet } while (0)
3758c8d2d96SKent Overstreet 
3768c8d2d96SKent Overstreet /**
3778c8d2d96SKent Overstreet  * closure_return - finish execution of a closure
3788c8d2d96SKent Overstreet  *
3798c8d2d96SKent Overstreet  * This is used to indicate that @cl is finished: when all outstanding refs on
3808c8d2d96SKent Overstreet  * @cl have been dropped @cl's ref on its parent closure (as passed to
3818c8d2d96SKent Overstreet  * closure_init()) will be dropped, if one was specified - thus this can be
3828c8d2d96SKent Overstreet  * thought of as returning to the parent closure.
3838c8d2d96SKent Overstreet  */
3848c8d2d96SKent Overstreet #define closure_return(_cl)	continue_at((_cl), NULL, NULL)
3858c8d2d96SKent Overstreet 
38606efa5f3SKent Overstreet void closure_return_sync(struct closure *cl);
38706efa5f3SKent Overstreet 
3888c8d2d96SKent Overstreet /**
3898c8d2d96SKent Overstreet  * continue_at_nobarrier - jump to another function without barrier
3908c8d2d96SKent Overstreet  *
3918c8d2d96SKent Overstreet  * Causes @fn to be executed out of @cl, in @wq context (or called directly if
3928c8d2d96SKent Overstreet  * @wq is NULL).
3938c8d2d96SKent Overstreet  *
3948c8d2d96SKent Overstreet  * The ref the caller of continue_at_nobarrier() had on @cl is now owned by @fn,
3958c8d2d96SKent Overstreet  * thus it's not safe to touch anything protected by @cl after a
3968c8d2d96SKent Overstreet  * continue_at_nobarrier().
3978c8d2d96SKent Overstreet  */
3988c8d2d96SKent Overstreet #define continue_at_nobarrier(_cl, _fn, _wq)				\
3998c8d2d96SKent Overstreet do {									\
4008c8d2d96SKent Overstreet 	set_closure_fn(_cl, _fn, _wq);					\
4018c8d2d96SKent Overstreet 	closure_queue(_cl);						\
4028c8d2d96SKent Overstreet } while (0)
4038c8d2d96SKent Overstreet 
4048c8d2d96SKent Overstreet /**
4058c8d2d96SKent Overstreet  * closure_return_with_destructor - finish execution of a closure,
4068c8d2d96SKent Overstreet  *				    with destructor
4078c8d2d96SKent Overstreet  *
4088c8d2d96SKent Overstreet  * Works like closure_return(), except @destructor will be called when all
4098c8d2d96SKent Overstreet  * outstanding refs on @cl have been dropped; @destructor may be used to safely
4108c8d2d96SKent Overstreet  * free the memory occupied by @cl, and it is called with the ref on the parent
4118c8d2d96SKent Overstreet  * closure still held - so @destructor could safely return an item to a
4128c8d2d96SKent Overstreet  * freelist protected by @cl's parent.
4138c8d2d96SKent Overstreet  */
4148c8d2d96SKent Overstreet #define closure_return_with_destructor(_cl, _destructor)		\
4158c8d2d96SKent Overstreet do {									\
4168c8d2d96SKent Overstreet 	set_closure_fn(_cl, _destructor, NULL);				\
4178c8d2d96SKent Overstreet 	closure_sub(_cl, CLOSURE_RUNNING - CLOSURE_DESTRUCTOR + 1);	\
4188c8d2d96SKent Overstreet } while (0)
4198c8d2d96SKent Overstreet 
4208c8d2d96SKent Overstreet /**
4218c8d2d96SKent Overstreet  * closure_call - execute @fn out of a new, uninitialized closure
4228c8d2d96SKent Overstreet  *
4238c8d2d96SKent Overstreet  * Typically used when running out of one closure, and we want to run @fn
4248c8d2d96SKent Overstreet  * asynchronously out of a new closure - @parent will then wait for @cl to
4258c8d2d96SKent Overstreet  * finish.
4268c8d2d96SKent Overstreet  */
closure_call(struct closure * cl,closure_fn fn,struct workqueue_struct * wq,struct closure * parent)4278c8d2d96SKent Overstreet static inline void closure_call(struct closure *cl, closure_fn fn,
4288c8d2d96SKent Overstreet 				struct workqueue_struct *wq,
4298c8d2d96SKent Overstreet 				struct closure *parent)
4308c8d2d96SKent Overstreet {
4318c8d2d96SKent Overstreet 	closure_init(cl, parent);
4328c8d2d96SKent Overstreet 	continue_at_nobarrier(cl, fn, wq);
4338c8d2d96SKent Overstreet }
4348c8d2d96SKent Overstreet 
435ced58fc7SKent Overstreet #define __closure_wait_event(waitlist, _cond)				\
436ced58fc7SKent Overstreet do {									\
437ced58fc7SKent Overstreet 	struct closure cl;						\
438ced58fc7SKent Overstreet 									\
439ced58fc7SKent Overstreet 	closure_init_stack(&cl);					\
440ced58fc7SKent Overstreet 									\
441ced58fc7SKent Overstreet 	while (1) {							\
442ced58fc7SKent Overstreet 		closure_wait(waitlist, &cl);				\
443ced58fc7SKent Overstreet 		if (_cond)						\
444ced58fc7SKent Overstreet 			break;						\
445ced58fc7SKent Overstreet 		closure_sync(&cl);					\
446ced58fc7SKent Overstreet 	}								\
447ced58fc7SKent Overstreet 	closure_wake_up(waitlist);					\
448ced58fc7SKent Overstreet 	closure_sync(&cl);						\
449ced58fc7SKent Overstreet } while (0)
450ced58fc7SKent Overstreet 
451ced58fc7SKent Overstreet #define closure_wait_event(waitlist, _cond)				\
452ced58fc7SKent Overstreet do {									\
453ced58fc7SKent Overstreet 	if (!(_cond))							\
454ced58fc7SKent Overstreet 		__closure_wait_event(waitlist, _cond);			\
455ced58fc7SKent Overstreet } while (0)
456ced58fc7SKent Overstreet 
457*04b670deSKent Overstreet #define __closure_wait_event_timeout(waitlist, _cond, _until)		\
458*04b670deSKent Overstreet ({									\
459*04b670deSKent Overstreet 	struct closure cl;						\
460*04b670deSKent Overstreet 	long _t;							\
461*04b670deSKent Overstreet 									\
462*04b670deSKent Overstreet 	closure_init_stack(&cl);					\
463*04b670deSKent Overstreet 									\
464*04b670deSKent Overstreet 	while (1) {							\
465*04b670deSKent Overstreet 		closure_wait(waitlist, &cl);				\
466*04b670deSKent Overstreet 		if (_cond) {						\
467*04b670deSKent Overstreet 			_t = max_t(long, 1L, _until - jiffies);		\
468*04b670deSKent Overstreet 			break;						\
469*04b670deSKent Overstreet 		}							\
470*04b670deSKent Overstreet 		_t = max_t(long, 0L, _until - jiffies);			\
471*04b670deSKent Overstreet 		if (!_t)						\
472*04b670deSKent Overstreet 			break;						\
473*04b670deSKent Overstreet 		closure_sync_timeout(&cl, _t);				\
474*04b670deSKent Overstreet 	}								\
475*04b670deSKent Overstreet 	closure_wake_up(waitlist);					\
476*04b670deSKent Overstreet 	closure_sync(&cl);						\
477*04b670deSKent Overstreet 	_t;								\
478*04b670deSKent Overstreet })
479*04b670deSKent Overstreet 
480*04b670deSKent Overstreet /*
481*04b670deSKent Overstreet  * Returns 0 if timeout expired, remaining time in jiffies (at least 1) if
482*04b670deSKent Overstreet  * condition became true
483*04b670deSKent Overstreet  */
484*04b670deSKent Overstreet #define closure_wait_event_timeout(waitlist, _cond, _timeout)		\
485*04b670deSKent Overstreet ({									\
486*04b670deSKent Overstreet 	unsigned long _until = jiffies + _timeout;			\
487*04b670deSKent Overstreet 	(_cond)								\
488*04b670deSKent Overstreet 		? max_t(long, 1L, _until - jiffies)			\
489*04b670deSKent Overstreet 		: __closure_wait_event_timeout(waitlist, _cond, _until);\
490*04b670deSKent Overstreet })
491*04b670deSKent Overstreet 
4928c8d2d96SKent Overstreet #endif /* _LINUX_CLOSURE_H */
493