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)
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>