@@ -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,
@@ -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);
}
/*
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@redhat.com> --- fs/select.c | 5 ++++- include/linux/poll.h | 20 ++++++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-)