Commit 4c5b7294 authored by Kent Overstreet's avatar Kent Overstreet

closures: closure_sync_timeout()

Add a new variant of closure_sync_timeout() that takes a timeout.

Note that when this returns -ETIME the closure will still be waiting on
something, i.e. it's not safe to return if you've got a stack allocated
closure.
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 9a768ab7
......@@ -194,6 +194,18 @@ static inline void closure_sync(struct closure *cl)
__closure_sync(cl);
}
int __closure_sync_timeout(struct closure *cl, unsigned long timeout);
static inline int closure_sync_timeout(struct closure *cl, unsigned long timeout)
{
#ifdef CONFIG_DEBUG_CLOSURES
BUG_ON(closure_nr_remaining(cl) != 1 && !cl->closure_get_happened);
#endif
return cl->closure_get_happened
? __closure_sync_timeout(cl, timeout)
: 0;
}
#ifdef CONFIG_DEBUG_CLOSURES
void closure_debug_create(struct closure *cl);
......
......@@ -139,6 +139,43 @@ void __sched __closure_sync(struct closure *cl)
}
EXPORT_SYMBOL(__closure_sync);
int __sched __closure_sync_timeout(struct closure *cl, unsigned long timeout)
{
struct closure_syncer s = { .task = current };
int ret = 0;
cl->s = &s;
continue_at(cl, closure_sync_fn, NULL);
while (1) {
set_current_state(TASK_UNINTERRUPTIBLE);
if (s.done)
break;
if (!timeout) {
/*
* Carefully undo the continue_at() - but only if it
* hasn't completed, i.e. the final closure_put() hasn't
* happened yet:
*/
unsigned old, new, v = atomic_read(&cl->remaining);
do {
old = v;
if (!old || (old & CLOSURE_RUNNING))
goto success;
new = old + CLOSURE_REMAINING_INITIALIZER;
} while ((v = atomic_cmpxchg(&cl->remaining, old, new)) != old);
ret = -ETIME;
}
timeout = schedule_timeout(timeout);
}
success:
__set_current_state(TASK_RUNNING);
return ret;
}
EXPORT_SYMBOL(__closure_sync_timeout);
#ifdef CONFIG_DEBUG_CLOSURES
static LIST_HEAD(closure_list);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment