Add a flag for poll_wait() showing that the caller wants the enqueue to be exclusive. It is similar to EPOLLEXCLUSIVE for epoll() but grants kernel poll users to opt-in with more efficient exclusive queuing where applicable. Signed-off-by: Peter Xu <peterx@xxxxxxxxxx> --- fs/select.c | 5 ++++- include/linux/poll.h | 20 ++++++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/fs/select.c b/fs/select.c index 0433448481e9..a3c9088e8d76 100644 --- a/fs/select.c +++ b/fs/select.c @@ -231,7 +231,10 @@ static void __pollwait(struct file *filp, wait_queue_head_t *wait_address, entry->key = p->_key; init_waitqueue_func_entry(&entry->wait, pollwake); entry->wait.private = pwq; - add_wait_queue(wait_address, &entry->wait); + if (flags & POLL_ENQUEUE_EXCLUSIVE) + add_wait_queue_exclusive(wait_address, &entry->wait); + else + add_wait_queue(wait_address, &entry->wait); } static int poll_schedule_timeout(struct poll_wqueues *pwq, int state, diff --git a/include/linux/poll.h b/include/linux/poll.h index cbad520fc65c..11af98ae579c 100644 --- a/include/linux/poll.h +++ b/include/linux/poll.h @@ -29,6 +29,8 @@ typedef unsigned int poll_flags; +#define POLL_ENQUEUE_EXCLUSIVE BIT(0) + struct poll_table_struct; /* @@ -46,10 +48,24 @@ typedef struct poll_table_struct { __poll_t _key; } poll_table; -static inline void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p) +static inline void __poll_wait(struct file *filp, wait_queue_head_t *wait_address, + poll_table *p, poll_flags flags) { if (p && p->_qproc && wait_address) - p->_qproc(filp, wait_address, p, 0); + p->_qproc(filp, wait_address, p, flags); +} + +static inline void poll_wait(struct file *filp, wait_queue_head_t *wait_address, + poll_table *p) +{ + __poll_wait(filp, wait_address, p, 0); +} + +static inline void poll_wait_exclusive(struct file *filp, + wait_queue_head_t *wait_address, + poll_table *p) +{ + __poll_wait(filp, wait_address, p, POLL_ENQUEUE_EXCLUSIVE); } /* -- 2.41.0