diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 194e67b1f..3f51f6bd3 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -586,7 +586,8 @@ enum { BINDER_LOOPER_STATE_EXITED = 0x04, BINDER_LOOPER_STATE_INVALID = 0x08, BINDER_LOOPER_STATE_WAITING = 0x10, - BINDER_LOOPER_STATE_POLL = 0x20, + BINDER_LOOPER_STATE_NEED_RETURN = 0x20, + BINDER_LOOPER_STATE_POLL = 0x40, }; /** @@ -4757,7 +4758,7 @@ static int binder_thread_release(struct binder_proc *proc, * If this thread used poll, make sure we remove the waitqueue * from any epoll data structures holding it with POLLFREE. * waitqueue_active() is safe to use here because we're holding - * the inner lock. + * the global lock. */ if ((thread->looper & BINDER_LOOPER_STATE_POLL) && waitqueue_active(&thread->wait)) { @@ -4775,6 +4776,17 @@ static int binder_thread_release(struct binder_proc *proc, if (thread->looper & BINDER_LOOPER_STATE_POLL) synchronize_rcu(); + /* + * If this thread used poll, make sure we remove the waitqueue + * from any epoll data structures holding it with POLLFREE. + * waitqueue_active() is safe to use here because we're holding + * the global lock. + */ + if ((thread->looper & BINDER_LOOPER_STATE_POLL) && + waitqueue_active(&thread->wait)) { + wake_up_poll(&thread->wait, POLLHUP | POLLFREE); + } + if (send_reply) binder_send_failed_reply(send_reply, BR_DEAD_REPLY); binder_release_work(proc, &thread->todo);