]> www.infradead.org Git - users/jedix/linux-maple.git/commit
epoll, wait: introduce poll_wait_fixed(), and use it in waitfds
authorNick Alcock <nick.alcock@oracle.com>
Tue, 18 Jun 2013 19:03:08 +0000 (20:03 +0100)
committerNick Alcock <nick.alcock@oracle.com>
Tue, 21 Jul 2015 14:28:56 +0000 (15:28 +0100)
commit7119aa28a1890b1fe6b938c7270887675fc30d67
tree77f89ded63074b926bbcaedb9983ef02e3b17254
parentb347b90b137db42281268c50803c0a70c9809709
epoll, wait: introduce poll_wait_fixed(), and use it in waitfds

The poll() machinery expects to be used with files, or things enough like files
that the wake_up key contains an indication as to whether this wakeup
corresponds to a POLLIN / POLLOUT / POLLERR event on this fd.  You can override
this in your poll_queue_proc, but the poll() and epoll() queue procs both have
this interpretation.

Unfortunately, it is not true for waitfds, wihch wait on the the wait_chldexit
waitqueue, whose key is a pointer to the task_struct of the task being killed.
We can't do anything with this key, but we certainly don't want the poll
machinery treating it as a bitmask and checking it against poll events!

So we introduce a new poll_wait() analogue, poll_wait_fixed().  This is used for
poll_wait() calls which know they must wait on waitqueues whose keys are not
a typecast representation of poll events, and passes in an extra argument to
the poll_queue_proc, which if nonzero is the event which a wakeup on this
waitqueue should be considered as equivalent to.  The poll_queue_proc can then
skip adding entirely if that fixed event is not included in the set to be
caught by this poll().

We also add a new poll_table_entry.fixed_key.  The poll_queue_proc can record
the fixed key it is passed in here, and reuse it at wakeup time to track that
a nonzero fixed key was passed in to poll_wait_fixed() and that the key should
be ignored in preference to fixed_key.

With this in place, you can say, e.g. (as waitfd now does)

poll_wait_fixed(file, &current->signal->wait_chldexit, wait,
POLLIN);

and the key passed to wakeups on the wait_chldexit waitqueue will be ignored:
the fd will always be treated as having raised POLLIN, waking up poll()s and
epoll()s that have specified that event.  (Obviously, a poll function that
calls this should return the same value from the poll function as was passed
to poll_wait_fixed(), or, as usual, zero if this was a spurious wakeup.)

Signed-off-by: Nick Alcock <nick.alcock@oracle.com>
drivers/vfio/virqfd.c
drivers/vhost/vhost.c
fs/eventpoll.c
fs/select.c
fs/waitfd.c
include/linux/poll.h
net/9p/trans_fd.c
virt/kvm/eventfd.c