Skip to content

Commit a22a960

Browse files
koverstreetaxboe
authored andcommitted
closures: fix a race on wakeup from closure_sync
The race was when a thread using closure_sync() notices cl->s->done == 1 before the thread calling closure_put() calls wake_up_process(). Then, it's possible for that thread to return and exit just before wake_up_process() is called - so we're trying to wake up a process that no longer exists. rcu_read_lock() is sufficient to protect against this, as there's an rcu barrier somewhere in the process teardown path. Signed-off-by: Kent Overstreet <[email protected]> Acked-by: Coly Li <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent d66c992 commit a22a960

File tree

1 file changed

+8
-2
lines changed

1 file changed

+8
-2
lines changed

drivers/md/bcache/closure.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,14 @@ struct closure_syncer {
105105

106106
static void closure_sync_fn(struct closure *cl)
107107
{
108-
cl->s->done = 1;
109-
wake_up_process(cl->s->task);
108+
struct closure_syncer *s = cl->s;
109+
struct task_struct *p;
110+
111+
rcu_read_lock();
112+
p = READ_ONCE(s->task);
113+
s->done = 1;
114+
wake_up_process(p);
115+
rcu_read_unlock();
110116
}
111117

112118
void __sched __closure_sync(struct closure *cl)

0 commit comments

Comments
 (0)