Skip to content

Commit a880b28

Browse files
committed
binder: use wake_up_pollfree()
wake_up_poll() uses nr_exclusive=1, so it's not guaranteed to wake up all exclusive waiters. Yet, POLLFREE *must* wake up all waiters. epoll and aio poll are fortunately not affected by this, but it's very fragile. Thus, the new function wake_up_pollfree() has been introduced. Convert binder to use wake_up_pollfree(). Reported-by: Linus Torvalds <[email protected]> Fixes: f5cb779 ("ANDROID: binder: remove waitqueue when thread exits.") Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Eric Biggers <[email protected]>
1 parent 42288cb commit a880b28

File tree

1 file changed

+9
-12
lines changed

1 file changed

+9
-12
lines changed

drivers/android/binder.c

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4422,23 +4422,20 @@ static int binder_thread_release(struct binder_proc *proc,
44224422
__release(&t->lock);
44234423

44244424
/*
4425-
* If this thread used poll, make sure we remove the waitqueue
4426-
* from any epoll data structures holding it with POLLFREE.
4427-
* waitqueue_active() is safe to use here because we're holding
4428-
* the inner lock.
4425+
* If this thread used poll, make sure we remove the waitqueue from any
4426+
* poll data structures holding it.
44294427
*/
4430-
if ((thread->looper & BINDER_LOOPER_STATE_POLL) &&
4431-
waitqueue_active(&thread->wait)) {
4432-
wake_up_poll(&thread->wait, EPOLLHUP | POLLFREE);
4433-
}
4428+
if (thread->looper & BINDER_LOOPER_STATE_POLL)
4429+
wake_up_pollfree(&thread->wait);
44344430

44354431
binder_inner_proc_unlock(thread->proc);
44364432

44374433
/*
4438-
* This is needed to avoid races between wake_up_poll() above and
4439-
* and ep_remove_waitqueue() called for other reasons (eg the epoll file
4440-
* descriptor being closed); ep_remove_waitqueue() holds an RCU read
4441-
* lock, so we can be sure it's done after calling synchronize_rcu().
4434+
* This is needed to avoid races between wake_up_pollfree() above and
4435+
* someone else removing the last entry from the queue for other reasons
4436+
* (e.g. ep_remove_wait_queue() being called due to an epoll file
4437+
* descriptor being closed). Such other users hold an RCU read lock, so
4438+
* we can be sure they're done after we call synchronize_rcu().
44424439
*/
44434440
if (thread->looper & BINDER_LOOPER_STATE_POLL)
44444441
synchronize_rcu();

0 commit comments

Comments
 (0)