aio poll and a new in-kernel poll API V12
Subsystems (38)
Hi all,
this series adds support for the IOCB_CMD_POLL operation to poll for the readyness of file descriptors using the aio subsystem. The API is based on patches that existed in RHAS2.1 and RHEL3, which means it already is supported by libaio. To implement the poll support efficiently new methods to poll are introduced in struct file_operations: get_poll_head and poll_mask. The first one returns a wait_queue_head to wait on (lifetime is bound by the file), and the second does a non-blocking check for the POLL* events. This allows aio poll to work without any additional context switches, unlike epoll.
This series sits on top of the aio-fsync series that also includes support for io_pgetevents.
The changes were sponsored by Scylladb, and improve performance of the seastar framework up to 10%, while also removing the need for a privileged SCHED_FIFO epoll listener thread.
git://git.infradead.org/users/hch/vfs.git aio-poll.12
Gitweb:
http://git.infradead.org/users/hch/vfs.git/shortlog/refs/heads/aio-poll.12
Libaio changes:
https://pagure.io/libaio.git io-poll
Seastar changes (not updated for the new io_pgetevens ABI yet):
https://github.com/avikivity/seastar/commits/aio
Changes since v11:
- simplify cancellation by completion poll requests from a workqueue if we can't take the ctx_lock
Changes since v10:
- fixed a mismerge that let a sock_rps_record_flow sneak into tcp_poll_mask
- remove the now unused struct proto_ops get_poll_head method
Changes since v9:
- add to the delayed_cancel_reqs earlier to avoid a race
- get rid of POLL_TO_PTR magic
Changes since v8:
- make delayed cancellation conditional again
- add a cancel_kiocb file operation to split delayed vs normal cancel
Changes since v7:
- make delayed cancellation safe and unconditional
Changes since v6:
- reworked cancellation
Changes since v5:
- small changelog updates
- rebased on top of the aio-fsync changes
Changes since v4:
- rebased ontop of Linux 4.16-rc4
Changes since v3:
- remove the pre-sleep ->poll_mask call in vfs_poll, allow ->get_poll_head to return POLL* values.
Changes since v2:
- removed a double initialization
- new vfs_get_poll_head helper
- document that ->get_poll_head can return NULL
- call ->poll_mask before sleeping
- various ACKs
- add conversion of random to ->poll_mask
- add conversion of af_alg to ->poll_mask
- lacking ->poll_mask support now returns -EINVAL for IOCB_CMD_POLL
- reshuffled the series so that prep patches and everything not requiring the new in-kernel poll API is in the beginning
Changes since v1:
- handle the NULL ->poll case in vfs_poll
- dropped the file argument to the ->poll_mask socket operation
- replace the ->pre_poll socket operation with ->get_poll_head as in the file operations
--
To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 1/31 fs: unexport poll_schedule_timeout
No users outside of select.c.
--- fs/select.c | 3 +-- include/linux/poll.h | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-)
fs/select.c +1 -2
@@ -233,7 +233,7 @@ static void __pollwait(struct file *filp, wait_queue_head_t *wait_address,add_wait_queue (wait_address, &entry->wait); } -int poll_schedule_timeout (struct poll_wqueues *pwq,int state, +static int poll_schedule_timeout (struct poll_wqueues *pwq,int state,ktime_t *expires,unsigned long slack) {int rc = -EINTR ;
@@ -258,7 +258,6 @@ int poll_schedule_timeout(struct poll_wqueues *pwq, int state,return rc; } -EXPORT_SYMBOL (poll_schedule_timeout);/** * poll_select_set_timeout - helper function to setup the timeout value
include/linux/poll.h +0 -2
@@ -96,8 +96,6 @@ struct poll_wqueues {extern void poll_initwait (struct poll_wqueues *pwq);extern void poll_freewait (struct poll_wqueues *pwq); -extern int poll_schedule_timeout (struct poll_wqueues *pwq,int state, -ktime_t *expires,unsigned long slack);extern u64 select_estimate_accuracy (struct timespec64 *tv);#define MAX_INT64_SECONDS (((s64)(~((u64)0)>>1)/HZ)-1)
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 2/31 fs: cleanup do_pollfd
In reply to Christoph HellwigUse straightline code with failure handling gotos instead of a lot of nested conditionals.
--- fs/select.c | 48 +++++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 25 deletions(-)
fs/select.c +23 -25
@@ -812,34 +812,32 @@ static inline __poll_t do_pollfd(struct pollfd *pollfd, poll_table *pwait,bool *can_busy_poll, __poll_t busy_flag) { -__poll_t mask; -int fd; - - mask =0 ; - fd = pollfd->fd; -if (fd >=0 ) { -struct fd f =fdget (fd); - mask =EPOLLNVAL ; -if (f.file) { -/* userland u16 ->events contains POLL... bitmap */ -__poll_t filter =demangle_poll (pollfd->events) | -EPOLLERR |EPOLLHUP ; - mask =DEFAULT_POLLMASK ; -if (f.file->f_op->poll) { - pwait->_key = filter; - pwait->_key |= busy_flag; - mask = f.file->f_op->poll (f.file, pwait); -if (mask & busy_flag) - *can_busy_poll = true; - } -/* Mask out unneeded events. */ - mask &= filter; -fdput (f); - } + int fd = pollfd->fd; +__poll_t mask =0 , filter; +struct fd f; + +if (fd <0 ) + goto out; + mask =EPOLLNVAL ; + f =fdget (fd); +if (!f.file) + goto out; + +/* userland u16 ->events contains POLL... bitmap */ + filter =demangle_poll (pollfd->events) |EPOLLERR |EPOLLHUP ; + mask =DEFAULT_POLLMASK ; +if (f.file->f_op->poll) { + pwait->_key = filter | busy_flag; + mask = f.file->f_op->poll (f.file, pwait); +if (mask & busy_flag) + *can_busy_poll = true; } + mask &= filter;/* Mask out unneeded events. */ +fdput (f); + +out:/* ... and so does ->revents */ pollfd->revents =mangle_poll (mask); -return mask; }
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 3/31 fs: update documentation to mention __poll_t and match the code
In reply to Christoph Hellwig--- Documentation/filesystems/Locking | 2 +- Documentation/filesystems/vfs.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
Documentation/filesystems/Locking +1 -1
@@ -439,7 +439,7 @@ prototypes: ssize_t (*read_iter) (struct kiocb *, struct iov_iter *); ssize_t (*write_iter) (struct kiocb *, struct iov_iter *); int (*iterate) (struct file *, struct dir_context *); - unsigned int (*poll) (struct file *, struct poll_table_struct *); + __poll_t (*poll) (struct file *, struct poll_table_struct *); long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); long (*compat_ioctl) (struct file *, unsigned int, unsigned long); int (*mmap) (struct file *, struct vm_area_struct *);
Documentation/filesystems/vfs.txt +1 -1
@@ -856,7 +856,7 @@ struct file_operations { ssize_t (*read_iter) (struct kiocb *, struct iov_iter *); ssize_t (*write_iter) (struct kiocb *, struct iov_iter *); int (*iterate) (struct file *, struct dir_context *); - unsigned int (*poll) (struct file *, struct poll_table_struct *); + __poll_t (*poll) (struct file *, struct poll_table_struct *); long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); long (*compat_ioctl) (struct file *, unsigned int, unsigned long); int (*mmap) (struct file *, struct vm_area_struct *);
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 4/31 fs: add new vfs_poll and file_can_poll helpers
In reply to Christoph HellwigThese abstract out calls to the poll method in preparation for changes in how we poll.
--- drivers/staging/comedi/drivers/serial2002.c | 4 ++-- drivers/vfio/virqfd.c | 2 +- drivers/vhost/vhost.c | 2 +- fs/eventpoll.c | 5 ++--- fs/select.c | 23 +++++++-------------- include/linux/poll.h | 12 +++++++++++ mm/memcontrol.c | 2 +- net/9p/trans_fd.c | 18 ++++------------ virt/kvm/eventfd.c | 2 +- 9 files changed, 32 insertions(+), 38 deletions(-)
drivers/staging/comedi/drivers/serial2002.c +2 -2
@@ -113,7 +113,7 @@ static void serial2002_tty_read_poll_wait(struct file *f, int timeout)long elapsed;__poll_t mask; - mask = f->f_op->poll (f, &table.pt); + mask =vfs_poll (f, &table.pt);if (mask & (EPOLLRDNORM |EPOLLRDBAND |EPOLLIN |EPOLLHUP |EPOLLERR )) {break ;
@@ -136,7 +136,7 @@ static int serial2002_tty_read(struct file *f, int timeout) result =-1 ;if (!IS_ERR (f)) { -if (f->f_op->poll) { +if (file_can_poll (f)) {serial2002_tty_read_poll_wait (f, timeout);if (kernel_read (f, &ch,1 , &pos) ==1 )
drivers/vfio/virqfd.c +1 -1
@@ -166,7 +166,7 @@ int vfio_virqfd_enable(void *opaque,init_waitqueue_func_entry (&virqfd->wait, virqfd_wakeup);init_poll_funcptr (&virqfd->pt, virqfd_ptable_queue_proc); - events = irqfd.file->f_op->poll (irqfd.file, &virqfd->pt); + events =vfs_poll (irqfd.file, &virqfd->pt);/* * Check if there was an event already pending on the eventfd
drivers/vhost/vhost.c +1 -1
@@ -208,7 +208,7 @@ int vhost_poll_start(struct vhost_poll *poll, struct file *file)if (poll->wqh)return 0 ; - mask = file->f_op->poll (file, &poll->table); + mask =vfs_poll (file, &poll->table);if (mask)vhost_poll_wakeup (&poll->wait,0 ,0 ,poll_to_key (mask));if (mask &EPOLLERR ) {
fs/eventpoll.c +2 -3
@@ -884,8 +884,7 @@ static __poll_t ep_item_poll(const struct epitem *epi, poll_table *pt, pt->_key = epi->event.events;if (!is_file_epoll (epi->ffd.file)) -return epi->ffd.file->f_op->poll (epi->ffd.file, pt) & - epi->event.events; +return vfs_poll (epi->ffd.file, pt) & epi->event.events; ep = epi->ffd.file->private_data;poll_wait (epi->ffd.file, &ep->poll_wait, pt);
@@ -2025,7 +2024,7 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,/* The target file descriptor must support poll */ error = -EPERM ; -if (!tf.file->f_op->poll) +if (!file_can_poll (tf.file)) goto error_tgt_fput;/* Check if EPOLLWAKEUP is allowed */
fs/select.c +8 -15
@@ -502,14 +502,10 @@ static int do_select(int n, fd_set_bits *fds, struct timespec64 *end_time)continue ; f =fdget (i);if (f.file) { -const struct file_operations *f_op; - f_op = f.file->f_op; - mask =DEFAULT_POLLMASK ; -if (f_op->poll) { -wait_key_set (wait, in, out, - bit, busy_flag); - mask = (*f_op->poll)(f.file, wait); - } +wait_key_set (wait, in, out, bit, + busy_flag); + mask =vfs_poll (f.file, wait); +fdput (f);if ((mask &POLLIN_SET ) && (in & bit)) { res_in |= bit;
@@ -825,13 +821,10 @@ static inline __poll_t do_pollfd(struct pollfd *pollfd, poll_table *pwait,/* userland u16 ->events contains POLL... bitmap */ filter =demangle_poll (pollfd->events) |EPOLLERR |EPOLLHUP ; - mask =DEFAULT_POLLMASK ; -if (f.file->f_op->poll) { - pwait->_key = filter | busy_flag; - mask = f.file->f_op->poll (f.file, pwait); -if (mask & busy_flag) - *can_busy_poll = true; - } + pwait->_key = filter | busy_flag; + mask =vfs_poll (f.file, pwait); +if (mask & busy_flag) + *can_busy_poll = true; mask &= filter;/* Mask out unneeded events. */ fdput (f);
include/linux/poll.h +12 -0
@@ -74,6 +74,18 @@ static inline void init_poll_funcptr(poll_table *pt, poll_queue_proc qproc) pt->_key = ~(__poll_t )0 ;/* all events enabled */ } +static inline bool file_can_poll (struct file *file) +{ +return file->f_op->poll; +} + +static inline __poll_t vfs_poll (struct file *file,struct poll_table_struct *pt) +{ +if (unlikely (!file->f_op->poll)) +return DEFAULT_POLLMASK ; +return file->f_op->poll (file, pt); +} +struct poll_table_entry {struct file *filp;__poll_t key;
mm/memcontrol.c +1 -1
@@ -3849,7 +3849,7 @@ static ssize_t memcg_write_event_control(struct kernfs_open_file *of,if (ret) goto out_put_css; - efile.file->f_op->poll (efile.file, &event->pt); +vfs_poll (efile.file, &event->pt);spin_lock (&memcg->event_list_lock);list_add (&event->list, &memcg->event_list);
net/9p/trans_fd.c +4 -14
@@ -231,7 +231,7 @@ static void p9_conn_cancel(struct p9_conn *m, int err)static __poll_t p9_fd_poll (struct p9_client *client,struct poll_table_struct *pt,int *err) { -__poll_t ret, n; +__poll_t ret;struct p9_trans_fd *ts =NULL ;if (client && client->status == Connected)
@@ -243,19 +243,9 @@ p9_fd_poll(struct p9_client *client, struct poll_table_struct *pt, int *err)return EPOLLERR ; } -if (!ts->rd->f_op->poll) - ret =DEFAULT_POLLMASK ; -else - ret = ts->rd->f_op->poll (ts->rd, pt); - -if (ts->rd != ts->wr) { -if (!ts->wr->f_op->poll) - n =DEFAULT_POLLMASK ; -else - n = ts->wr->f_op->poll (ts->wr, pt); - ret = (ret & ~EPOLLOUT ) | (n & ~EPOLLIN ); - } - + ret =vfs_poll (ts->rd, pt); +if (ts->rd != ts->wr) + ret = (ret & ~EPOLLOUT ) | (vfs_poll (ts->wr, pt) & ~EPOLLIN );return ret; }
virt/kvm/eventfd.c +1 -1
@@ -397,7 +397,7 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)* Check if there was an event already pending on the eventfd * before we registered, and trigger it as if we didn't miss it. */ - events = f.file->f_op->poll (f.file, &irqfd->pt); + events =vfs_poll (f.file, &irqfd->pt);if (events &EPOLLIN )schedule_work (&irqfd->inject);
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 5/31 fs: introduce new ->get_poll_head and ->poll_mask methods
In reply to Christoph Hellwig->get_poll_head returns the waitqueue that the poll operation is going to sleep on. Note that this means we can only use a single waitqueue for the poll, unlike some current drivers that use two waitqueues for different events. But now that we have keyed wakeups and heavily use those for poll there aren't that many good reason left to keep the multiple waitqueues, and if there are any ->poll is still around, the driver just won't support aio poll.
--- Documentation/filesystems/Locking | 7 ++++++- Documentation/filesystems/vfs.txt | 13 +++++++++++++ fs/select.c | 23 +++++++++++++++++++++++ include/linux/fs.h | 2 ++ include/linux/poll.h | 12 ++++++------ 5 files changed, 50 insertions(+), 7 deletions(-)
Documentation/filesystems/Locking +6 -1
@@ -440,6 +440,8 @@ prototypes: ssize_t (*write_iter) (struct kiocb *, struct iov_iter *); int (*iterate) (struct file *, struct dir_context *); __poll_t (*poll) (struct file *, struct poll_table_struct *); + struct wait_queue_head * (*get_poll_head)(struct file *, __poll_t); + __poll_t (*poll_mask) (struct file *, __poll_t); long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); long (*compat_ioctl) (struct file *, unsigned int, unsigned long); int (*mmap) (struct file *, struct vm_area_struct *);
@@ -470,7 +472,7 @@ prototypes: }; locking rules: - All may block. + All except for ->poll_mask may block. ->llseek() locking has moved from llseek to the individual llseek implementations. If your fs is not using generic_file_llseek, you
@@ -498,6 +500,9 @@ in sys_read() and friends. the lease within the individual filesystem to record the result of the operation +->poll_mask can be called with or without the waitqueue lock for the waitqueue +returned from ->get_poll_head. + --------------------------- dquot_operations ------------------------------- prototypes: int (*write_dquot) (struct dquot *);
Documentation/filesystems/vfs.txt +13 -0
@@ -857,6 +857,8 @@ struct file_operations { ssize_t (*write_iter) (struct kiocb *, struct iov_iter *); int (*iterate) (struct file *, struct dir_context *); __poll_t (*poll) (struct file *, struct poll_table_struct *); + struct wait_queue_head * (*get_poll_head)(struct file *, __poll_t); + __poll_t (*poll_mask) (struct file *, __poll_t); long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); long (*compat_ioctl) (struct file *, unsigned int, unsigned long); int (*mmap) (struct file *, struct vm_area_struct *);
@@ -901,6 +903,17 @@ otherwise noted. activity on this file and (optionally) go to sleep until there is activity. Called by the select(2) and poll(2) system calls + get_poll_head: Returns the struct wait_queue_head that callers can + wait on. Callers need to check the returned events using ->poll_mask + once woken. Can return NULL to indicate polling is not supported, + or any error code using the ERR_PTR convention to indicate that a + grave error occured and ->poll_mask shall not be called. + + poll_mask: return the mask of EPOLL* values describing the file descriptor + state. Called either before going to sleep on the waitqueue returned by + get_poll_head, or after it has been woken. If ->get_poll_head and + ->poll_mask are implemented ->poll does not need to be implement. + unlocked_ioctl: called by the ioctl(2) system call. compat_ioctl: called by the ioctl(2) system call when 32 bit system calls
fs/select.c +23 -0
@@ -34,6 +34,29 @@#include <linux/uaccess.h> +__poll_t vfs_poll (struct file *file,struct poll_table_struct *pt) +{ +if (file->f_op->poll) { +return file->f_op->poll (file, pt); + }else if (file_has_poll_mask (file)) { +unsigned int events =poll_requested_events (pt); +struct wait_queue_head *head; + +if (pt && pt->_qproc) { + head = file->f_op->get_poll_head (file, events); +if (!head) +return DEFAULT_POLLMASK ; +if (IS_ERR (head)) +return EPOLLERR ; + pt->_qproc (file, head, pt); + } + +return file->f_op->poll_mask (file, events); + }else { +return DEFAULT_POLLMASK ; + } +} +EXPORT_SYMBOL_GPL (vfs_poll);/* * Estimate expected accuracy in ns from a timeval.
include/linux/fs.h +2 -0
@@ -1711,6 +1711,8 @@ struct file_operations {int (*iterate) (struct file *,struct dir_context *);int (*iterate_shared) (struct file *,struct dir_context *);__poll_t (*poll) (struct file *,struct poll_table_struct *); +struct wait_queue_head * (*get_poll_head)(struct file *,__poll_t ); +__poll_t (*poll_mask) (struct file *,__poll_t );long (*unlocked_ioctl) (struct file *,unsigned int ,unsigned long );long (*compat_ioctl) (struct file *,unsigned int ,unsigned long );int (*mmap) (struct file *,struct vm_area_struct *);
include/linux/poll.h +6 -6
@@ -74,18 +74,18 @@ static inline void init_poll_funcptr(poll_table *pt, poll_queue_proc qproc) pt->_key = ~(__poll_t )0 ;/* all events enabled */ } -static inline bool file_can_poll (struct file *file) +static inline bool file_has_poll_mask (struct file *file) { -return file->f_op->poll; +return file->f_op->get_poll_head && file->f_op->poll_mask; } -static inline __poll_t vfs_poll (struct file *file,struct poll_table_struct *pt) +static inline bool file_can_poll (struct file *file) { -if (unlikely (!file->f_op->poll)) -return DEFAULT_POLLMASK ; -return file->f_op->poll (file, pt); +return file->f_op->poll ||file_has_poll_mask (file); } +__poll_t vfs_poll (struct file *file,struct poll_table_struct *pt); +struct poll_table_entry {struct file *filp;__poll_t key;
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 6/31 aio: simplify KIOCB_KEY handling
In reply to Christoph HellwigNo need to pass the key field to lookup_iocb to compare it with KIOCB_KEY, as we can do that right after retrieving it from userspace. Also move the KIOCB_KEY definition to aio.c as it is an internal value not used by any other place in the kernel.
--- fs/aio.c | 14 +++++++------- include/linux/aio.h | 2 -- 2 files changed, 7 insertions(+), 9 deletions(-)
fs/aio.c +7 -7
@@ -46,6 +46,8 @@#include "internal.h" +#define KIOCB_KEY 0 +#define AIO_RING_MAGIC 0xa10a10a1#define AIO_RING_COMPAT_FEATURES 1#define AIO_RING_INCOMPAT_FEATURES 0
@@ -1812,15 +1814,12 @@ COMPAT_SYSCALL_DEFINE3(io_submit, compat_aio_context_t, ctx_id,* Finds a given iocb for cancellation. */ static struct aio_kiocb * -lookup_kiocb (struct kioctx *ctx,struct iocb __user *iocb,u32 key) +lookup_kiocb (struct kioctx *ctx,struct iocb __user *iocb) {struct aio_kiocb *kiocb;assert_spin_locked (&ctx->ctx_lock); -if (key !=KIOCB_KEY ) -return NULL ; -/* TODO: use a hash or array, this sucks. */ list_for_each_entry (kiocb, &ctx->active_reqs, ki_list) {if (kiocb->ki_user_iocb == iocb)
@@ -1847,9 +1846,10 @@ SYSCALL_DEFINE3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb,u32 key;int ret; - ret =get_user (key, &iocb->aio_key); -if (unlikely (ret)) +if (unlikely (get_user (key, &iocb->aio_key)))return -EFAULT ; +if (unlikely (key !=KIOCB_KEY )) +return -EINVAL ; ctx =lookup_ioctx (ctx_id);if (unlikely (!ctx))
@@ -1857,7 +1857,7 @@ SYSCALL_DEFINE3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb,spin_lock_irq (&ctx->ctx_lock); - kiocb =lookup_kiocb (ctx, iocb, key); + kiocb =lookup_kiocb (ctx, iocb);if (kiocb) ret =kiocb_cancel (kiocb);else
include/linux/aio.h +0 -2
@@ -8,8 +8,6 @@ struct kioctx;struct kiocb ;struct mm_struct ; -#define KIOCB_KEY 0 -typedef int (kiocb_cancel_fn )(struct kiocb *);/* prototypes */
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 7/31 aio: simplify cancellation
In reply to Christoph HellwigWith the current aio code there is no need for the magic KIOCB_CANCELLED value, as a cancelation just kicks the driver to queue the completion ASAP, with all actual completion handling done in another thread. Given that both the completion path and cancelation take the context lock there is no need for magic cmpxchg loops either. If we remove iocbs from the active list before calling ->ki_cancel we can also rely on the invariant thay anything found on the list has a ->ki_cancel callback and can be cancelled, further simplifing the code.
--- fs/aio.c | 49 ++++++------------------------------------------- 1 file changed, 6 insertions(+), 43 deletions(-)
fs/aio.c +6 -43
@@ -164,19 +164,6 @@ struct fsync_iocb {bool datasync; }; -/* -* We use ki_cancel == KIOCB_CANCELLED to indicate that a kiocb has been either -* cancelled or completed (this makes a certain amount of sense because -* successful cancellation - io_cancel() - does deliver the completion to -* userspace). -* -* And since most things don't implement kiocb cancellation and we'd really like -* kiocb completion to be lockless when possible, we use ki_cancel to -* synchronize cancellation and completion - we only set it to KIOCB_CANCELLED -* with xchg() or cmpxchg(), see batch_complete_aio() and kiocb_cancel(). -*/ -#define KIOCB_CANCELLED ((void *) (~0ULL)) - struct aio_kiocb { union { struct kiocb rw;
@@ -574,27 +561,6 @@ void kiocb_set_cancel_fn(struct kiocb *iocb, kiocb_cancel_fn *cancel) }EXPORT_SYMBOL (kiocb_set_cancel_fn); -static int kiocb_cancel (struct aio_kiocb *kiocb) -{ -kiocb_cancel_fn *old, *cancel; - -/* -* Don't want to set kiocb->ki_cancel = KIOCB_CANCELLED unless it -* actually has a cancel function, hence the cmpxchg() -*/ - - cancel =READ_ONCE (kiocb->ki_cancel); -do { -if (!cancel || cancel ==KIOCB_CANCELLED ) -return -EINVAL ; - - old = cancel; - cancel =cmpxchg (&kiocb->ki_cancel, old,KIOCB_CANCELLED ); - }while (cancel != old); - -return cancel (&kiocb->rw); -} -/* * free_ioctx() should be RCU delayed to synchronize against the RCU * protected lookup_ioctx() and also needs process context to call
@@ -641,9 +607,8 @@ static void free_ioctx_users(struct percpu_ref *ref)while (!list_empty (&ctx->active_reqs)) { req =list_first_entry (&ctx->active_reqs, struct aio_kiocb, ki_list); -list_del_init (&req->ki_list); -kiocb_cancel (req); + req->ki_cancel (&req->rw); }spin_unlock_irq (&ctx->ctx_lock);
@@ -1843,8 +1808,8 @@ SYSCALL_DEFINE3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb, {struct kioctx *ctx;struct aio_kiocb *kiocb; +int ret = -EINVAL ;u32 key; -int ret;if (unlikely (get_user (key, &iocb->aio_key)))return -EFAULT ;
@@ -1856,13 +1821,11 @@ SYSCALL_DEFINE3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb,return -EINVAL ;spin_lock_irq (&ctx->ctx_lock); - kiocb =lookup_kiocb (ctx, iocb); -if (kiocb) - ret =kiocb_cancel (kiocb); -else - ret = -EINVAL ; - +if (kiocb) { +list_del_init (&kiocb->ki_list); + ret = kiocb->ki_cancel (&kiocb->rw); + }spin_unlock_irq (&ctx->ctx_lock);if (!ret) {
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 8/31 aio: implement IOCB_CMD_POLL
In reply to Christoph HellwigSimple one-shot poll through the io_submit() interface. To poll for a file descriptor the application should submit an iocb of type IOCB_CMD_POLL. It will poll the fd for the events specified in the the first 32 bits of the aio_buf field of the iocb.
Unlike poll or epoll without EPOLLONESHOT this interface always works in one shot mode, that is once the iocb is completed, it will have to be resubmitted.
--- fs/aio.c | 134 ++++++++++++++++++++++++++++++++++- include/uapi/linux/aio_abi.h | 6 +- 2 files changed, 135 insertions(+), 5 deletions(-)
fs/aio.c +133 -1
@@ -5,6 +5,7 @@* Implements an efficient asynchronous io interface. * * Copyright 2000, 2001, 2002 Red Hat, Inc. All Rights Reserved. +* Copyright 2018 Christoph Hellwig. * * See ../COPYING for licensing terms. */
@@ -164,10 +165,22 @@ struct fsync_iocb {bool datasync; }; +struct poll_iocb { +struct file *file; +__poll_t events; +struct wait_queue_head *head; + +union { +struct wait_queue_entry wait; +struct work_struct work; + }; +}; +struct aio_kiocb {union {struct kiocb rw;struct fsync_iocb fsync; +struct poll_iocb poll; };struct kioctx *ki_ctx;
@@ -1558,7 +1571,6 @@ static int aio_fsync(struct fsync_iocb *req, struct iocb *iocb, bool datasync)if (unlikely (iocb->aio_buf || iocb->aio_offset || iocb->aio_nbytes || iocb->aio_rw_flags))return -EINVAL ; - req->file =fget (iocb->aio_fildes);if (unlikely (!req->file))return -EBADF ;
@@ -1573,6 +1585,124 @@ static int aio_fsync(struct fsync_iocb *req, struct iocb *iocb, bool datasync)return -EIOCBQUEUED ; } +/* need to use list_del_init so we can check if item was present */ +static inline bool __aio_poll_remove (struct poll_iocb *req) +{ +if (list_empty (&req->wait.entry)) +return false; +list_del_init (&req->wait.entry); +return true; +} + +static inline void __aio_poll_complete (struct poll_iocb *req,__poll_t mask) +{ + struct aio_kiocb *iocb = container_of(req, struct aio_kiocb, poll); + +fput (req->file); +aio_complete (iocb,mangle_poll (mask),0 ); +} + +static void aio_poll_work (struct work_struct *work) +{ + struct poll_iocb *req = container_of(work, struct poll_iocb, work); + +__aio_poll_complete (req, req->events); +} + +static int aio_poll_cancel (struct kiocb *iocb) +{ + struct aio_kiocb *aiocb = container_of(iocb, struct aio_kiocb, rw); +struct poll_iocb *req = &aiocb->poll; +struct wait_queue_head *head = req->head; +bool found = false; + +spin_lock (&head->lock); + found =__aio_poll_remove (req); +spin_unlock (&head->lock); + +if (found) { + req->events =0 ; +INIT_WORK (&req->work, aio_poll_work); +schedule_work (&req->work); + } +return 0 ; +} + +static int aio_poll_wake (struct wait_queue_entry *wait,unsigned mode,int sync, +void *key) +{ + struct poll_iocb *req = container_of(wait, struct poll_iocb, wait); +struct file *file = req->file; +__poll_t mask =key_to_poll (key); + +assert_spin_locked (&req->head->lock); + +/* for instances that support it check for an event match first: */ +if (mask && !(mask & req->events)) +return 0 ; + + mask = file->f_op->poll_mask (file, req->events); +if (!mask) +return 0 ; + +__aio_poll_remove (req); + + req->events = mask; +INIT_WORK (&req->work, aio_poll_work); +schedule_work (&req->work); +return 1 ; +} + +static ssize_t aio_poll (struct aio_kiocb *aiocb,struct iocb *iocb) +{ +struct kioctx *ctx = aiocb->ki_ctx; +struct poll_iocb *req = &aiocb->poll; +__poll_t mask; + +/* reject any unknown events outside the normal event mask. */ +if ((u16 )iocb->aio_buf != iocb->aio_buf) +return -EINVAL ; +/* reject fields that are not defined for poll */ +if (iocb->aio_offset || iocb->aio_nbytes || iocb->aio_rw_flags) +return -EINVAL ; + + req->events =demangle_poll (iocb->aio_buf) |POLLERR |POLLHUP ; + req->file =fget (iocb->aio_fildes); +if (unlikely (!req->file)) +return -EBADF ; +if (!file_has_poll_mask (req->file)) + goto out_fail; + + req->head = req->file->f_op->get_poll_head (req->file, req->events); +if (!req->head) + goto out_fail; +if (IS_ERR (req->head)) { + mask =EPOLLERR ; + goto done; + } + +init_waitqueue_func_entry (&req->wait, aio_poll_wake); + aiocb->ki_cancel = aio_poll_cancel; + +spin_lock_irq (&ctx->ctx_lock); +list_add_tail (&aiocb->ki_list, &ctx->active_reqs); + +spin_lock (&req->head->lock); + mask = req->file->f_op->poll_mask (req->file, req->events); +if (!mask) +__add_wait_queue (req->head, &req->wait); +spin_unlock (&req->head->lock); + +spin_unlock_irq (&ctx->ctx_lock); +done: +if (mask) +__aio_poll_complete (req, mask); +return -EIOCBQUEUED ; +out_fail: +fput (req->file); +return -EINVAL ;/* same as no support for IOCB_CMD_POLL */ +} +static int io_submit_one (struct kioctx *ctx,struct iocb __user *user_iocb,struct iocb *iocb,bool compat) {
@@ -1641,6 +1771,8 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,break ;case IOCB_CMD_FDSYNC : ret =aio_fsync (&req->fsync, iocb, true); +case IOCB_CMD_POLL : + ret =aio_poll (req, iocb);break ;default :pr_debug ("invalid aio operation %d\n" , iocb->aio_lio_opcode);
include/uapi/linux/aio_abi.h +2 -4
@@ -39,10 +39,8 @@ enum {IOCB_CMD_PWRITE =1 ,IOCB_CMD_FSYNC =2 ,IOCB_CMD_FDSYNC =3 , -/* These two are experimental. -* IOCB_CMD_PREADX = 4, -* IOCB_CMD_POLL = 5, -*/ +/* 4 was the experimental IOCB_CMD_PREADX */ +IOCB_CMD_POLL =5 ,IOCB_CMD_NOOP =6 ,IOCB_CMD_PREADV =7 , IOCB_CMD_PWRITEV = 8,
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
Al Viro
maintainerRe: [PATCH 08/31] aio: implement IOCB_CMD_POLL
fs/aio.c static int aio_fsync(struct fsync_iocb *req, struct iocb *iocb, bool datasync) · line 1603
Quoted 7 lines · Christoph Hellwig
fs/aio.c +7
-0+static inline void __aio_poll_complete (struct poll_iocb *req,__poll_t mask) +{ + struct aio_kiocb *iocb = container_of(req, struct aio_kiocb, poll); + +fput (req->file); +aio_complete (iocb,mangle_poll (mask),0 ); +}
Careful.
fs/aio.c static int aio_fsync(struct fsync_iocb *req, struct iocb *iocb, bool datasync) · line 1621
Quoted 10 lines
fs/aio.c +10
-0+static int aio_poll_cancel (struct kiocb *iocb) +{ + struct aio_kiocb *aiocb = container_of(iocb, struct aio_kiocb, rw); +struct poll_iocb *req = &aiocb->poll; +struct wait_queue_head *head = req->head; +bool found = false; + +spin_lock (&head->lock); + found =__aio_poll_remove (req); +spin_unlock (&head->lock);
What's to guarantee that req->head has not been freed by that point?
Look: wakeup finds ->ctx_lock held, so it leaves the sucker on the list, removes it from queue and schedules the call of __aio_poll_complete(). Which gets executed just as we hit aio_poll_cancel(), starting with fput().
You really want to do aio_complete() before fput(). That way you know that req->wait is alive and well at least until iocb gets removed from the list.
fs/aio.c static int aio_fsync(struct fsync_iocb *req, struct iocb *iocb, bool datasync) · line 1669
Quoted 1 line
fs/aio.c +1
-0+ req->events =demangle_poll (iocb->aio_buf) |POLLERR |POLLHUP ;
EPOLLERR | EPOLLHUP, please. The values are equal to POLLERR and POLLHUP on all architectures, but let's avoid misannotations.
fs/aio.c static int aio_fsync(struct fsync_iocb *req, struct iocb *iocb, bool datasync) · line 1693
Quoted 7 lines
fs/aio.c +7
-0+spin_lock_irq (&ctx->ctx_lock); +list_add_tail (&aiocb->ki_list, &ctx->active_reqs); + +spin_lock (&req->head->lock); + mask = req->file->f_op->poll_mask (req->file, req->events); +if (!mask) +__add_wait_queue (req->head, &req->wait);
ITYM
if (!mask) {
__add_wait_queue(req->head, &req->wait);
list_add_tail(&aiocb->ki_list, &ctx->active_reqs);
}What's the point of exposing it to aio_poll_cancel() when it has never been on waitqueue?
--
To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"[email protected]">[email protected]</a>
Al Viro
maintainerRe: [PATCH 08/31] aio: implement IOCB_CMD_POLL
Quoted 25 lines · Al Viro
fs/aio.c static int aio_fsync(struct fsync_iocb *req, struct iocb *iocb, bool datasync) · line 1603
Quoted 6 lines
fs/aio.c +6
-0+{ + struct aio_kiocb *iocb = container_of(req, struct aio_kiocb, poll); + +fput (req->file); +aio_complete (iocb,mangle_poll (mask),0 ); +}Careful.
fs/aio.c static int aio_fsync(struct fsync_iocb *req, struct iocb *iocb, bool datasync) · line 1621
Quoted 10 lines
fs/aio.c +10
-0+static int aio_poll_cancel (struct kiocb *iocb) +{ + struct aio_kiocb *aiocb = container_of(iocb, struct aio_kiocb, rw); +struct poll_iocb *req = &aiocb->poll; +struct wait_queue_head *head = req->head; +bool found = false; + +spin_lock (&head->lock); + found =__aio_poll_remove (req); +spin_unlock (&head->lock);What's to guarantee that
req->headhas not been freed by that point?
Look: wakeup finds ->ctx_lock held, so it leaves the sucker on the list, removes it from queue and schedules the call of__aio_poll_complete(). Which gets executed just as we hitaio_poll_cancel(), starting withfput().
Quoted 2 lines
You really want to do
aio_complete()beforefput(). That way you know thatreq->waitis alive and well at least until iocb gets removed from the list.
Oh, bugger...
wakeup
removed from queue
schedule __aio_poll_complete()
cancel
grab ctx->lock remove from list
work
aio_complete()
check if it's in the list
it isn't, move on to free the sucker
cancel
call ->ki_cancel() BOOM
Looks like we want to call ->ki_cancel() *BEFORE* removing from the list, as well as doing fput() after aio_complete(). The same ordering, BTW, goes for aio_read() et.al.
Look:
CPU1: io_cancel() grabs ->ctx_lock, finds iocb and removes it from the list.
CPU2: aio_rw_complete() on that iocb. Since the sucker is not in the list
anymore, we do NOT spin on ->ctx_lock and proceed to free iocb
CPU1: pass freed iocb to ->ki_cancel(). BOOM.
and if we have fput() done first (in aio_rw_complete()) we are vulnerable to
CPU1: io_cancel() grabs ->ctx_lock, finds iocb and removes it from the list.
CPU2: aio_rw_complete() on that iocb. fput() done, opening us to rmmod.
CPU1: call ->ki_cancel(), which points to freed memory now. BOOM.
--
To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"[email protected]">[email protected]</a>
Al Viro
maintainerRe: [PATCH 08/31] aio: implement IOCB_CMD_POLL
Quoted 21 lines · Al Viro
Oh, bugger...
wakeup
removed from queue
schedule__aio_poll_complete()cancel
grab ctx->lock remove from listwork
aio_complete()
check if it's in the list
it isn't, move on to free the sucker
cancelcall ->ki_cancel() BOOMLooks like we want to call ->ki_cancel() *BEFORE* removing from the list, as well as doing
fput()afteraio_complete(). The same ordering, BTW, goes foraio_read()et.al.
Quoted 5 lines
Look:
CPU1:io_cancel()grabs ->ctx_lock, finds iocb and removes it from the list.
CPU2:aio_rw_complete()on that iocb. Since the sucker is not in the list
anymore, we do NOT spin on ->ctx_lock and proceed to free iocb
CPU1: pass freed iocb to ->ki_cancel(). BOOM.
BTW, it seems that the mainline is vulnerable to this one. I might be missing something, but...
--
To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"[email protected]">[email protected]</a>
Al Viro
maintainerYAaioRace (was Re: [PATCH 08/31] aio: implement IOCB_CMD_POLL)
Quoted 4 lines · Al Viro
Quoted 4 lines
Looks like we want to call ->ki_cancel() *BEFORE* removing from the list, as well as doing
fput()afteraio_complete(). The same ordering, BTW, goes foraio_read()et.al.
Quoted 8 lines
Quoted 5 lines
Look:
CPU1:io_cancel()grabs ->ctx_lock, finds iocb and removes it from the list.
CPU2:aio_rw_complete()on that iocb. Since the sucker is not in the list
anymore, we do NOT spin on ->ctx_lock and proceed to free iocb
CPU1: pass freed iocb to ->ki_cancel(). BOOM.BTW, it seems that the mainline is vulnerable to this one. I might be missing something, but...
It is, but with a different attack vector - io_cancel(2) won't do it (it does not remove from the list at all), but io_destroy(2) bloody well will.
IMO, we need this in mainline; unless somebody has a problem with it, to #fixes it goes:
fix io_destroy()/aio_complete() race
If io_destroy() gets to cancelling everything that can be cancelled and gets to kiocb_cancel() calling the function driver has left in ->ki_cancel, it becomes vulnerable to a race with IO completion. At that point req is already taken off the list and aio_complete() does *NOT* spin until we (in free_ioctx_users()) releases ->ctx_lock. As the result, it proceeds to kiocb_free(), freing req just it gets passed to ->ki_cancel().
Fix is simple - remove from the list after the call of kiocb_cancel(). All instances of ->ki_cancel() already have to cope with the being called with iocb still on list - that's what happens in io_cancel(2).
---
fs/aio.c +1 -2
@@ -634,9 +634,8 @@ static void free_ioctx_users(struct percpu_ref *ref)while (!list_empty (&ctx->active_reqs)) { req =list_first_entry (&ctx->active_reqs, struct aio_kiocb, ki_list); - -list_del_init (&req->ki_list);kiocb_cancel (req); +list_del_init (&req->ki_list); }spin_unlock_irq (&ctx->ctx_lock);
--
To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 9/31 aio: try to complete poll iocbs without context switch
In reply to Christoph HellwigIf we can acquire ctx_lock without spinning we can just remove our iocb from the active_reqs list, and thus complete the iocbs from the wakeup context.
--- fs/aio.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-)
fs/aio.c +17 -3
@@ -1632,6 +1632,7 @@ static int aio_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync, void *key) { struct poll_iocb *req = container_of(wait, struct poll_iocb, wait); + struct aio_kiocb *iocb = container_of(req, struct aio_kiocb, poll);struct file *file = req->file;__poll_t mask =key_to_poll (key);
@@ -1647,9 +1648,22 @@ static int aio_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync,__aio_poll_remove (req); - req->events = mask; -INIT_WORK (&req->work, aio_poll_work); -schedule_work (&req->work); +/* +* Try completing without a context switch if we can acquire ctx_lock +* without spinning. Otherwise we need to defer to a workqueue to +* avoid a deadlock due to the lock order. +*/ +if (spin_trylock (&iocb->ki_ctx->ctx_lock)) { +list_del_init (&iocb->ki_list); +spin_unlock (&iocb->ki_ctx->ctx_lock); + +__aio_poll_complete (req, mask); + }else { + req->events = mask; +INIT_WORK (&req->work, aio_poll_work); +schedule_work (&req->work); + } +return 1 ; }
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 10/31 net: refactor socket_poll
In reply to Christoph HellwigFactor out two busy poll related helpers for late reuse, and remove a command that isn't very helpful, especially with the __poll_t annotations in place.
--- include/net/busy_poll.h | 15 +++++++++++++++ net/socket.c | 21 ++++----------------- 2 files changed, 19 insertions(+), 17 deletions(-)
include/net/busy_poll.h +15 -0
@@ -121,6 +121,21 @@ static inline void sk_busy_loop(struct sock *sk, int nonblock)#endif } +static inline void sock_poll_busy_loop (struct socket *sock,__poll_t events) +{ +if (sk_can_busy_loop (sock->sk) && + events && (events &POLL_BUSY_LOOP )) { +/* once, only if requested by syscall */ +sk_busy_loop (sock->sk,1 ); + } +} + +/* if this socket can poll_ll, tell the system call */ +static inline __poll_t sock_poll_busy_flag (struct socket *sock) +{ +return sk_can_busy_loop (sock->sk) ?POLL_BUSY_LOOP :0 ; +} +/* used in the NIC receive handler to mark the skb */ static inline void skb_mark_napi_id (struct sk_buff *skb,struct napi_struct *napi)
net/socket.c +4 -17
@@ -1117,24 +1117,11 @@ EXPORT_SYMBOL(sock_create_lite);/* No kernel lock held - perfect */ static __poll_t sock_poll (struct file *file,poll_table *wait) { -__poll_t busy_flag =0 ; -struct socket *sock; - -/* -* We can't return errors to poll, so it's either yes or no. -*/ - sock = file->private_data; - -if (sk_can_busy_loop (sock->sk)) { -/* this socket can poll_ll so tell the system call */ - busy_flag =POLL_BUSY_LOOP ; - -/* once, only if requested by syscall */ -if (wait && (wait->_key &POLL_BUSY_LOOP )) -sk_busy_loop (sock->sk,1 ); - } +struct socket *sock = file->private_data; +__poll_t events =poll_requested_events (wait); -return busy_flag | sock->ops->poll (file, sock, wait); +sock_poll_busy_loop (sock, events); +return sock->ops->poll (file, sock, wait) |sock_poll_busy_flag (sock); }static int sock_mmap (struct file *file,struct vm_area_struct *vma)
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 11/31 net: add support for ->poll_mask in proto_ops
In reply to Christoph HellwigThe socket file operations still implement ->poll until all protocols are switched over.
--- include/linux/net.h | 1 + net/socket.c | 48 ++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 44 insertions(+), 5 deletions(-)
include/linux/net.h +1 -0
@@ -147,6 +147,7 @@ struct proto_ops {int (*getname) (struct socket *sock,struct sockaddr *addr,int peer); +__poll_t (*poll_mask) (struct socket *sock,__poll_t events);__poll_t (*poll) (struct file *file,struct socket *sock,struct poll_table_struct *wait); int (*ioctl) (struct socket *sock, unsigned int cmd,
net/socket.c +43 -5
71 lines not on this page · raw message
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 12/31 net: remove sock_no_poll
In reply to Christoph HellwigNow that sock_poll handles a NULL ->poll or ->poll_mask there is no need for a stub.
--- crypto/af_alg.c | 1 - crypto/algif_hash.c | 2 -- crypto/algif_rng.c | 1 - drivers/isdn/mISDN/socket.c | 1 - drivers/net/ppp/pptp.c | 1 - include/net/sock.h | 2 -- net/bluetooth/bnep/sock.c | 1 - net/bluetooth/cmtp/sock.c | 1 - net/bluetooth/hidp/sock.c | 1 - net/core/sock.c | 6 ------ 10 files changed, 17 deletions(-)
crypto/af_alg.c +0 -1
@@ -347,7 +347,6 @@ static const struct proto_ops alg_proto_ops = { .sendpage = sock_no_sendpage, .sendmsg = sock_no_sendmsg, .recvmsg = sock_no_recvmsg, - .poll = sock_no_poll, .bind = alg_bind, .release = af_alg_release,
crypto/algif_hash.c +0 -2
@@ -288,7 +288,6 @@ static struct proto_ops algif_hash_ops = { .mmap = sock_no_mmap, .bind = sock_no_bind, .setsockopt = sock_no_setsockopt, - .poll = sock_no_poll, .release = af_alg_release, .sendmsg = hash_sendmsg,
@@ -396,7 +395,6 @@ static struct proto_ops algif_hash_ops_nokey = { .mmap = sock_no_mmap, .bind = sock_no_bind, .setsockopt = sock_no_setsockopt, - .poll = sock_no_poll, .release = af_alg_release, .sendmsg = hash_sendmsg_nokey,
crypto/algif_rng.c +0 -1
@@ -106,7 +106,6 @@ static struct proto_ops algif_rng_ops = { .bind = sock_no_bind, .accept = sock_no_accept, .setsockopt = sock_no_setsockopt, - .poll = sock_no_poll, .sendmsg = sock_no_sendmsg, .sendpage = sock_no_sendpage,
drivers/isdn/mISDN/socket.c +0 -1
@@ -745,7 +745,6 @@ static const struct proto_ops base_sock_ops = { .getname = sock_no_getname, .sendmsg = sock_no_sendmsg, .recvmsg = sock_no_recvmsg, - .poll = sock_no_poll, .listen = sock_no_listen, .shutdown = sock_no_shutdown, .setsockopt = sock_no_setsockopt,
drivers/net/ppp/pptp.c +0 -1
@@ -624,7 +624,6 @@ static const struct proto_ops pptp_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = pptp_getname, - .poll = sock_no_poll, .listen = sock_no_listen, .shutdown = sock_no_shutdown, .setsockopt = sock_no_setsockopt,
include/net/sock.h +0 -2
@@ -1591,8 +1591,6 @@ int sock_no_connect(struct socket *, struct sockaddr *, int, int);int sock_no_socketpair (struct socket *,struct socket *);int sock_no_accept (struct socket *,struct socket *,int ,bool );int sock_no_getname (struct socket *,struct sockaddr *,int ); -__poll_t sock_no_poll (struct file *,struct socket *, -struct poll_table_struct *);int sock_no_ioctl (struct socket *,unsigned int ,unsigned long );int sock_no_listen (struct socket *,int );int sock_no_shutdown (struct socket *,int );
net/bluetooth/bnep/sock.c +0 -1
@@ -175,7 +175,6 @@ static const struct proto_ops bnep_sock_ops = { .getname = sock_no_getname, .sendmsg = sock_no_sendmsg, .recvmsg = sock_no_recvmsg, - .poll = sock_no_poll, .listen = sock_no_listen, .shutdown = sock_no_shutdown, .setsockopt = sock_no_setsockopt,
net/bluetooth/cmtp/sock.c +0 -1
@@ -178,7 +178,6 @@ static const struct proto_ops cmtp_sock_ops = { .getname = sock_no_getname, .sendmsg = sock_no_sendmsg, .recvmsg = sock_no_recvmsg, - .poll = sock_no_poll, .listen = sock_no_listen, .shutdown = sock_no_shutdown, .setsockopt = sock_no_setsockopt,
net/bluetooth/hidp/sock.c +0 -1
@@ -208,7 +208,6 @@ static const struct proto_ops hidp_sock_ops = { .getname = sock_no_getname, .sendmsg = sock_no_sendmsg, .recvmsg = sock_no_recvmsg, - .poll = sock_no_poll, .listen = sock_no_listen, .shutdown = sock_no_shutdown, .setsockopt = sock_no_setsockopt,
net/core/sock.c +0 -6
@@ -2567,12 +2567,6 @@ int sock_no_getname(struct socket *sock, struct sockaddr *saddr, }EXPORT_SYMBOL (sock_no_getname); -__poll_t sock_no_poll (struct file *file,struct socket *sock,poll_table *pt) -{ -return 0 ; -} -EXPORT_SYMBOL (sock_no_poll); -int sock_no_ioctl (struct socket *sock,unsigned int cmd,unsigned long arg) {return -EOPNOTSUPP ;
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 13/31 net/tcp: convert to ->poll_mask
In reply to Christoph Hellwig--- include/net/tcp.h | 3 +-- net/ipv4/af_inet.c | 2 +- net/ipv4/tcp.c | 23 ++++++----------------- net/ipv6/af_inet6.c | 2 +- 4 files changed, 9 insertions(+), 21 deletions(-)
include/net/tcp.h +1 -2
@@ -388,8 +388,7 @@ bool tcp_peer_is_proven(struct request_sock *req, struct dst_entry *dst);void tcp_close (struct sock *sk,long timeout);void tcp_init_sock (struct sock *sk);void tcp_init_transfer (struct sock *sk,int bpf_op); -__poll_t tcp_poll (struct file *file,struct socket *sock, -struct poll_table_struct *wait); +__poll_t tcp_poll_mask (struct socket *sock,__poll_t events);int tcp_getsockopt (struct sock *sk,int level,int optname,char __user *optval,int __user *optlen); int tcp_setsockopt(struct sock *sk, int level, int optname,
net/ipv4/af_inet.c +1 -1
@@ -986,7 +986,7 @@ const struct proto_ops inet_stream_ops = { .socketpair = sock_no_socketpair, .accept = inet_accept, .getname = inet_getname, - .poll = tcp_poll, + .poll_mask = tcp_poll_mask, .ioctl = inet_ioctl, .listen = inet_listen, .shutdown = inet_shutdown,
net/ipv4/tcp.c +6 -17
@@ -494,32 +494,21 @@ static inline bool tcp_stream_is_readable(const struct tcp_sock *tp, }/* -* Wait for a TCP event. -* -* Note that we don't need to lock the socket, as the upper poll layers -* take care of normal races (between the test and the event) and we don't -* go look at any of the socket buffers directly. +* Socket is not locked. We are protected from async events by poll logic and +* correct handling of state changes made by other threads is impossible in +* any case. */ -__poll_t tcp_poll (struct file *file,struct socket *sock,poll_table *wait) +__poll_t tcp_poll_mask (struct socket *sock,__poll_t events) { -__poll_t mask;struct sock *sk = sock->sk;const struct tcp_sock *tp =tcp_sk (sk); +__poll_t mask =0 ;int state; -sock_poll_wait (file,sk_sleep (sk), wait); - state =inet_sk_state_load (sk);if (state ==TCP_LISTEN )return inet_csk_listen_poll (sk); -/* Socket is not locked. We are protected from async events -* by poll logic and correct handling of state changes -* made by other threads is impossible in any case. -*/ - - mask =0 ; -/* * EPOLLHUP is certainly not done right. But poll() doesn't * have a notion of HUP in just one direction, and for a
@@ -600,7 +589,7 @@ __poll_t tcp_poll(struct file *file, struct socket *sock, poll_table *wait)return mask; } -EXPORT_SYMBOL (tcp_poll); +EXPORT_SYMBOL (tcp_poll_mask);int tcp_ioctl (struct sock *sk,int cmd,unsigned long arg) {
net/ipv6/af_inet6.c +1 -1
@@ -571,7 +571,7 @@ const struct proto_ops inet6_stream_ops = { .socketpair = sock_no_socketpair, /* a do nothing */ .accept = inet_accept, /* ok */ .getname = inet6_getname, - .poll = tcp_poll, /* ok */ + .poll_mask = tcp_poll_mask, /* ok */ .ioctl = inet6_ioctl, /* must change */ .listen = inet_listen, /* ok */ .shutdown = inet_shutdown, /* ok */
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 14/31 net/unix: convert to ->poll_mask
In reply to Christoph Hellwig--- net/unix/af_unix.c | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-)
net/unix/af_unix.c +11 -19
@@ -638,9 +638,8 @@ static int unix_stream_connect(struct socket *, struct sockaddr *,static int unix_socketpair (struct socket *,struct socket *);static int unix_accept (struct socket *,struct socket *,int ,bool );static int unix_getname (struct socket *,struct sockaddr *,int ); -static __poll_t unix_poll (struct file *,struct socket *,poll_table *); -static __poll_t unix_dgram_poll (struct file *,struct socket *, -poll_table *); +static __poll_t unix_poll_mask (struct socket *,__poll_t ); +static __poll_t unix_dgram_poll_mask (struct socket *,__poll_t );static int unix_ioctl (struct socket *,unsigned int ,unsigned long );static int unix_shutdown (struct socket *,int );static int unix_stream_sendmsg (struct socket *,struct msghdr *,size_t );
@@ -681,7 +680,7 @@ static const struct proto_ops unix_stream_ops = { .socketpair = unix_socketpair, .accept = unix_accept, .getname = unix_getname, - .poll = unix_poll, + .poll_mask = unix_poll_mask, .ioctl = unix_ioctl, .listen = unix_listen, .shutdown = unix_shutdown,
@@ -704,7 +703,7 @@ static const struct proto_ops unix_dgram_ops = { .socketpair = unix_socketpair, .accept = sock_no_accept, .getname = unix_getname, - .poll = unix_dgram_poll, + .poll_mask = unix_dgram_poll_mask, .ioctl = unix_ioctl, .listen = sock_no_listen, .shutdown = unix_shutdown,
@@ -726,7 +725,7 @@ static const struct proto_ops unix_seqpacket_ops = { .socketpair = unix_socketpair, .accept = unix_accept, .getname = unix_getname, - .poll = unix_dgram_poll, + .poll_mask = unix_dgram_poll_mask, .ioctl = unix_ioctl, .listen = unix_listen, .shutdown = unix_shutdown,
@@ -2630,13 +2629,10 @@ static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)return err; } -static __poll_t unix_poll (struct file *file,struct socket *sock,poll_table *wait) +static __poll_t unix_poll_mask (struct socket *sock,__poll_t events) {struct sock *sk = sock->sk; -__poll_t mask; - -sock_poll_wait (file,sk_sleep (sk), wait); - mask =0 ; +__poll_t mask =0 ;/* exceptional events? */ if (sk->sk_err)
@@ -2665,15 +2661,11 @@ static __poll_t unix_poll(struct file *file, struct socket *sock, poll_table *wareturn mask; } -static __poll_t unix_dgram_poll (struct file *file,struct socket *sock, -poll_table *wait) +static __poll_t unix_dgram_poll_mask (struct socket *sock,__poll_t events) {struct sock *sk = sock->sk, *other; -unsigned int writable; -__poll_t mask; - -sock_poll_wait (file,sk_sleep (sk), wait); - mask =0 ; +int writable; +__poll_t mask =0 ;/* exceptional events? */ if (sk->sk_err || !skb_queue_empty (&sk->sk_error_queue))
@@ -2699,7 +2691,7 @@ static __poll_t unix_dgram_poll(struct file *file, struct socket *sock, }/* No write status requested, avoid expensive OUT tests. */ -if (!(poll_requested_events (wait) & (EPOLLWRBAND |EPOLLWRNORM |EPOLLOUT ))) +if (!(events & (EPOLLWRBAND |EPOLLWRNORM |EPOLLOUT )))return mask; writable =unix_writable (sk);
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 15/31 net: convert datagram_poll users tp ->poll_mask
In reply to Christoph Hellwig--- drivers/isdn/mISDN/socket.c | 2 +- drivers/net/ppp/pppoe.c | 2 +- drivers/staging/ipx/af_ipx.c | 2 +- include/linux/skbuff.h | 3 +-- include/net/udp.h | 2 +- net/appletalk/ddp.c | 2 +- net/ax25/af_ax25.c | 2 +- net/bluetooth/hci_sock.c | 2 +- net/can/bcm.c | 2 +- net/can/raw.c | 2 +- net/core/datagram.c | 13 ++++--------- net/decnet/af_decnet.c | 6 +++--- net/ieee802154/socket.c | 4 ++-- net/ipv4/af_inet.c | 6 +++--- net/ipv4/udp.c | 10 +++++----- net/ipv6/af_inet6.c | 2 +- net/ipv6/raw.c | 4 ++-- net/kcm/kcmsock.c | 10 +++++----- net/key/af_key.c | 2 +- net/l2tp/l2tp_ip.c | 2 +- net/l2tp/l2tp_ip6.c | 2 +- net/l2tp/l2tp_ppp.c | 2 +- net/llc/af_llc.c | 2 +- net/netlink/af_netlink.c | 2 +- net/netrom/af_netrom.c | 2 +- net/nfc/rawsock.c | 4 ++-- net/packet/af_packet.c | 9 ++++----- net/phonet/socket.c | 2 +- net/qrtr/qrtr.c | 2 +- net/rose/af_rose.c | 2 +- net/x25/af_x25.c | 2 +- 31 files changed, 52 insertions(+), 59 deletions(-)
drivers/isdn/mISDN/socket.c +1 -1
@@ -588,7 +588,7 @@ static const struct proto_ops data_sock_ops = { .getname = data_sock_getname, .sendmsg = mISDN_sock_sendmsg, .recvmsg = mISDN_sock_recvmsg, - .poll = datagram_poll, + .poll_mask = datagram_poll_mask, .listen = sock_no_listen, .shutdown = sock_no_shutdown, .setsockopt = data_sock_setsockopt,
drivers/net/ppp/pppoe.c +1 -1
@@ -1122,7 +1122,7 @@ static const struct proto_ops pppoe_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = pppoe_getname, - .poll = datagram_poll, + .poll_mask = datagram_poll_mask, .listen = sock_no_listen, .shutdown = sock_no_shutdown, .setsockopt = sock_no_setsockopt,
drivers/staging/ipx/af_ipx.c +1 -1
@@ -1965,7 +1965,7 @@ static const struct proto_ops ipx_dgram_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = ipx_getname, - .poll = datagram_poll, + .poll_mask = datagram_poll_mask, .ioctl = ipx_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = ipx_compat_ioctl,
include/linux/skbuff.h +1 -2
@@ -3250,8 +3250,7 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned flags, int *peeked, int *off, int *err);struct sk_buff *skb_recv_datagram (struct sock *sk,unsigned flags,int noblock,int *err); -__poll_t datagram_poll (struct file *file,struct socket *sock, -struct poll_table_struct *wait); +__poll_t datagram_poll_mask (struct socket *sock,__poll_t events);int skb_copy_datagram_iter (const struct sk_buff *from,int offset,struct iov_iter *to,int size); static inline int skb_copy_datagram_msg(const struct sk_buff *from, int offset,
include/net/udp.h +1 -1
@@ -276,7 +276,7 @@ int udp_init_sock(struct sock *sk);int udp_pre_connect (struct sock *sk,struct sockaddr *uaddr,int addr_len);int __udp_disconnect (struct sock *sk,int flags);int udp_disconnect (struct sock *sk,int flags); -__poll_t udp_poll (struct file *file,struct socket *sock,poll_table *wait); +__poll_t udp_poll_mask (struct socket *sock,__poll_t events);struct sk_buff *skb_udp_tunnel_segment (struct sk_buff *skb,netdev_features_t features,bool is_ipv6);
net/appletalk/ddp.c +1 -1
@@ -1869,7 +1869,7 @@ static const struct proto_ops atalk_dgram_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = atalk_getname, - .poll = datagram_poll, + .poll_mask = datagram_poll_mask, .ioctl = atalk_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = atalk_compat_ioctl,
net/ax25/af_ax25.c +1 -1
@@ -1954,7 +1954,7 @@ static const struct proto_ops ax25_proto_ops = { .socketpair = sock_no_socketpair, .accept = ax25_accept, .getname = ax25_getname, - .poll = datagram_poll, + .poll_mask = datagram_poll_mask, .ioctl = ax25_ioctl, .listen = ax25_listen, .shutdown = ax25_shutdown,
net/bluetooth/hci_sock.c +1 -1
@@ -1975,7 +1975,7 @@ static const struct proto_ops hci_sock_ops = { .sendmsg = hci_sock_sendmsg, .recvmsg = hci_sock_recvmsg, .ioctl = hci_sock_ioctl, - .poll = datagram_poll, + .poll_mask = datagram_poll_mask, .listen = sock_no_listen, .shutdown = sock_no_shutdown, .setsockopt = hci_sock_setsockopt,
net/can/bcm.c +1 -1
@@ -1669,7 +1669,7 @@ static const struct proto_ops bcm_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = sock_no_getname, - .poll = datagram_poll, + .poll_mask = datagram_poll_mask, .ioctl = can_ioctl, /* use can_ioctl() from af_can.c */ .listen = sock_no_listen, .shutdown = sock_no_shutdown,
net/can/raw.c +1 -1
@@ -843,7 +843,7 @@ static const struct proto_ops raw_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = raw_getname, - .poll = datagram_poll, + .poll_mask = datagram_poll_mask, .ioctl = can_ioctl, /* use can_ioctl() from af_can.c */ .listen = sock_no_listen, .shutdown = sock_no_shutdown,
net/core/datagram.c +4 -9
@@ -819,9 +819,8 @@ EXPORT_SYMBOL(skb_copy_and_csum_datagram_msg);/** * datagram_poll - generic datagram poll -* @file: file struct * @sock: socket -* @wait: poll table +* @events to wait for * * Datagram poll: Again totally generic. This also handles * sequenced packet sockets providing the socket receive queue
@@ -831,14 +830,10 @@ EXPORT_SYMBOL(skb_copy_and_csum_datagram_msg);* and you use a different write policy from sock_writeable() * then please supply your own write_space callback. */ -__poll_t datagram_poll (struct file *file,struct socket *sock, -poll_table *wait) +__poll_t datagram_poll_mask (struct socket *sock,__poll_t events) {struct sock *sk = sock->sk; -__poll_t mask; - -sock_poll_wait (file,sk_sleep (sk), wait); - mask =0 ; +__poll_t mask =0 ;/* exceptional events? */ if (sk->sk_err || !skb_queue_empty (&sk->sk_error_queue))
@@ -871,4 +866,4 @@ __poll_t datagram_poll(struct file *file, struct socket *sock,return mask; } -EXPORT_SYMBOL (datagram_poll); +EXPORT_SYMBOL (datagram_poll_mask);
net/decnet/af_decnet.c +3 -3
@@ -1207,11 +1207,11 @@ static int dn_getname(struct socket *sock, struct sockaddr *uaddr,int peer) } -static __poll_t dn_poll (struct file *file,struct socket *sock,poll_table *wait) +static __poll_t dn_poll_mask (struct socket *sock,__poll_t events) {struct sock *sk = sock->sk;struct dn_scp *scp =DN_SK (sk); -__poll_t mask =datagram_poll (file, sock, wait); +__poll_t mask =datagram_poll_mask (sock, events);if (!skb_queue_empty (&scp->other_receive_queue)) mask |=EPOLLRDBAND ;
@@ -2344,7 +2344,7 @@ static const struct proto_ops dn_proto_ops = { .socketpair = sock_no_socketpair, .accept = dn_accept, .getname = dn_getname, - .poll = dn_poll, + .poll_mask = dn_poll_mask, .ioctl = dn_ioctl, .listen = dn_listen, .shutdown = dn_shutdown,
net/ieee802154/socket.c +2 -2
@@ -423,7 +423,7 @@ static const struct proto_ops ieee802154_raw_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = sock_no_getname, - .poll = datagram_poll, + .poll_mask = datagram_poll_mask, .ioctl = ieee802154_sock_ioctl, .listen = sock_no_listen, .shutdown = sock_no_shutdown,
@@ -969,7 +969,7 @@ static const struct proto_ops ieee802154_dgram_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = sock_no_getname, - .poll = datagram_poll, + .poll_mask = datagram_poll_mask, .ioctl = ieee802154_sock_ioctl, .listen = sock_no_listen, .shutdown = sock_no_shutdown,
net/ipv4/af_inet.c +3 -3
@@ -1018,7 +1018,7 @@ const struct proto_ops inet_dgram_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = inet_getname, - .poll = udp_poll, + .poll_mask = udp_poll_mask, .ioctl = inet_ioctl, .listen = sock_no_listen, .shutdown = inet_shutdown,
@@ -1039,7 +1039,7 @@ EXPORT_SYMBOL(inet_dgram_ops);/* * For SOCK_RAW sockets; should be the same as inet_dgram_ops but without -* udp_poll +* udp_poll_mask */ static const struct proto_ops inet_sockraw_ops = { .family =PF_INET ,
@@ -1050,7 +1050,7 @@ static const struct proto_ops inet_sockraw_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = inet_getname, - .poll = datagram_poll, + .poll_mask = datagram_poll_mask, .ioctl = inet_ioctl, .listen = sock_no_listen, .shutdown = inet_shutdown,
net/ipv4/udp.c +5 -5
@@ -2498,7 +2498,7 @@ int compat_udp_getsockopt(struct sock *sk, int level, int optname,* udp_poll - wait for a UDP event. * @file - file struct * @sock - socket -* @wait - poll table +* @events - events to wait for * * This is same as datagram poll, except for the special case of * blocking sockets. If application is using a blocking fd
@@ -2507,23 +2507,23 @@ int compat_udp_getsockopt(struct sock *sk, int level, int optname,* but then block when reading it. Add special case code * to work around these arguably broken applications. */ -__poll_t udp_poll (struct file *file,struct socket *sock,poll_table *wait) +__poll_t udp_poll_mask (struct socket *sock,__poll_t events) { -__poll_t mask =datagram_poll (file, sock, wait); +__poll_t mask =datagram_poll_mask (sock, events);struct sock *sk = sock->sk;if (!skb_queue_empty (&udp_sk (sk)->reader_queue)) mask |=EPOLLIN |EPOLLRDNORM ;/* Check for false positives due to checksum errors */ -if ((mask &EPOLLRDNORM ) && !(file->f_flags &O_NONBLOCK ) && +if ((mask &EPOLLRDNORM ) && !(sock->file->f_flags &O_NONBLOCK ) && !(sk->sk_shutdown &RCV_SHUTDOWN ) &&first_packet_length (sk) ==-1 ) mask &= ~(EPOLLIN |EPOLLRDNORM );return mask; } -EXPORT_SYMBOL (udp_poll); +EXPORT_SYMBOL (udp_poll_mask);int udp_abort (struct sock *sk,int err) {
net/ipv6/af_inet6.c +1 -1
@@ -601,7 +601,7 @@ const struct proto_ops inet6_dgram_ops = { .socketpair = sock_no_socketpair, /* a do nothing */ .accept = sock_no_accept, /* a do nothing */ .getname = inet6_getname, - .poll = udp_poll, /* ok */ + .poll_mask = udp_poll_mask, /* ok */ .ioctl = inet6_ioctl, /* must change */ .listen = sock_no_listen, /* ok */ .shutdown = inet_shutdown, /* ok */
net/ipv6/raw.c +2 -2
@@ -1345,7 +1345,7 @@ void raw6_proc_exit(void) }#endif /* CONFIG_PROC_FS */ -/* Same as inet6_dgram_ops, sans udp_poll. */ +/* Same as inet6_dgram_ops, sans udp_poll_mask. */ const struct proto_ops inet6_sockraw_ops = { .family =PF_INET6 , .owner =THIS_MODULE ,
@@ -1355,7 +1355,7 @@ const struct proto_ops inet6_sockraw_ops = { .socketpair = sock_no_socketpair, /* a do nothing */ .accept = sock_no_accept, /* a do nothing */ .getname = inet6_getname, - .poll = datagram_poll, /* ok */ + .poll_mask = datagram_poll_mask, /* ok */ .ioctl = inet6_ioctl, /* must change */ .listen = sock_no_listen, /* ok */ .shutdown = inet_shutdown, /* ok */
net/kcm/kcmsock.c +5 -5
@@ -1336,9 +1336,9 @@ static void init_kcm_sock(struct kcm_sock *kcm, struct kcm_mux *mux)struct list_head *head;int index =0 ; -/* For SOCK_SEQPACKET sock type, datagram_poll checks the sk_state, so -* we set sk_state, otherwise epoll_wait always returns right away with -* EPOLLHUP +/* For SOCK_SEQPACKET sock type, datagram_poll_mask checks the sk_state, +* so we set sk_state, otherwise epoll_wait always returns right away +* with EPOLLHUP */ kcm->sk.sk_state =TCP_ESTABLISHED ;
@@ -1903,7 +1903,7 @@ static const struct proto_ops kcm_dgram_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = sock_no_getname, - .poll = datagram_poll, + .poll_mask = datagram_poll_mask, .ioctl = kcm_ioctl, .listen = sock_no_listen, .shutdown = sock_no_shutdown,
@@ -1924,7 +1924,7 @@ static const struct proto_ops kcm_seqpacket_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = sock_no_getname, - .poll = datagram_poll, + .poll_mask = datagram_poll_mask, .ioctl = kcm_ioctl, .listen = sock_no_listen, .shutdown = sock_no_shutdown,
net/key/af_key.c +1 -1
@@ -3726,7 +3726,7 @@ static const struct proto_ops pfkey_ops = {/* Now the operations that really occur. */ .release = pfkey_release, - .poll = datagram_poll, + .poll_mask = datagram_poll_mask, .sendmsg = pfkey_sendmsg, .recvmsg = pfkey_recvmsg, };
net/l2tp/l2tp_ip.c +1 -1
@@ -613,7 +613,7 @@ static const struct proto_ops l2tp_ip_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = l2tp_ip_getname, - .poll = datagram_poll, + .poll_mask = datagram_poll_mask, .ioctl = inet_ioctl, .listen = sock_no_listen, .shutdown = inet_shutdown,
net/l2tp/l2tp_ip6.c +1 -1
@@ -754,7 +754,7 @@ static const struct proto_ops l2tp_ip6_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = l2tp_ip6_getname, - .poll = datagram_poll, + .poll_mask = datagram_poll_mask, .ioctl = inet6_ioctl, .listen = sock_no_listen, .shutdown = inet_shutdown,
net/l2tp/l2tp_ppp.c +1 -1
@@ -1806,7 +1806,7 @@ static const struct proto_ops pppol2tp_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = pppol2tp_getname, - .poll = datagram_poll, + .poll_mask = datagram_poll_mask, .listen = sock_no_listen, .shutdown = sock_no_shutdown, .setsockopt = pppol2tp_setsockopt,
net/llc/af_llc.c +1 -1
@@ -1189,7 +1189,7 @@ static const struct proto_ops llc_ui_ops = { .socketpair = sock_no_socketpair, .accept = llc_ui_accept, .getname = llc_ui_getname, - .poll = datagram_poll, + .poll_mask = datagram_poll_mask, .ioctl = llc_ui_ioctl, .listen = llc_ui_listen, .shutdown = llc_ui_shutdown,
net/netlink/af_netlink.c +1 -1
@@ -2673,7 +2673,7 @@ static const struct proto_ops netlink_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = netlink_getname, - .poll = datagram_poll, + .poll_mask = datagram_poll_mask, .ioctl = netlink_ioctl, .listen = sock_no_listen, .shutdown = sock_no_shutdown,
net/netrom/af_netrom.c +1 -1
@@ -1367,7 +1367,7 @@ static const struct proto_ops nr_proto_ops = { .socketpair = sock_no_socketpair, .accept = nr_accept, .getname = nr_getname, - .poll = datagram_poll, + .poll_mask = datagram_poll_mask, .ioctl = nr_ioctl, .listen = nr_listen, .shutdown = sock_no_shutdown,
net/nfc/rawsock.c +2 -2
@@ -284,7 +284,7 @@ static const struct proto_ops rawsock_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = sock_no_getname, - .poll = datagram_poll, + .poll_mask = datagram_poll_mask, .ioctl = sock_no_ioctl, .listen = sock_no_listen, .shutdown = sock_no_shutdown,
@@ -304,7 +304,7 @@ static const struct proto_ops rawsock_raw_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = sock_no_getname, - .poll = datagram_poll, + .poll_mask = datagram_poll_mask, .ioctl = sock_no_ioctl, .listen = sock_no_listen, .shutdown = sock_no_shutdown,
net/packet/af_packet.c +4 -5
@@ -4108,12 +4108,11 @@ static int packet_ioctl(struct socket *sock, unsigned int cmd,return 0 ; } -static __poll_t packet_poll (struct file *file,struct socket *sock, -poll_table *wait) +static __poll_t packet_poll_mask (struct socket *sock,__poll_t events) {struct sock *sk = sock->sk;struct packet_sock *po =pkt_sk (sk); -__poll_t mask =datagram_poll (file, sock, wait); +__poll_t mask =datagram_poll_mask (sock, events);spin_lock_bh (&sk->sk_receive_queue.lock);if (po->rx_ring.pg_vec) {
@@ -4455,7 +4454,7 @@ static const struct proto_ops packet_ops_spkt = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = packet_getname_spkt, - .poll = datagram_poll, + .poll_mask = datagram_poll_mask, .ioctl = packet_ioctl, .listen = sock_no_listen, .shutdown = sock_no_shutdown,
@@ -4476,7 +4475,7 @@ static const struct proto_ops packet_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = packet_getname, - .poll = packet_poll, + .poll_mask = packet_poll_mask, .ioctl = packet_ioctl, .listen = sock_no_listen, .shutdown = sock_no_shutdown,
net/phonet/socket.c +1 -1
@@ -448,7 +448,7 @@ const struct proto_ops phonet_dgram_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = pn_socket_getname, - .poll = datagram_poll, + .poll_mask = datagram_poll_mask, .ioctl = pn_socket_ioctl, .listen = sock_no_listen, .shutdown = sock_no_shutdown,
net/qrtr/qrtr.c +1 -1
@@ -1023,7 +1023,7 @@ static const struct proto_ops qrtr_proto_ops = { .recvmsg = qrtr_recvmsg, .getname = qrtr_getname, .ioctl = qrtr_ioctl, - .poll = datagram_poll, + .poll_mask = datagram_poll_mask, .shutdown = sock_no_shutdown, .setsockopt = sock_no_setsockopt, .getsockopt = sock_no_getsockopt,
net/rose/af_rose.c +1 -1
@@ -1482,7 +1482,7 @@ static const struct proto_ops rose_proto_ops = { .socketpair = sock_no_socketpair, .accept = rose_accept, .getname = rose_getname, - .poll = datagram_poll, + .poll_mask = datagram_poll_mask, .ioctl = rose_ioctl, .listen = rose_listen, .shutdown = sock_no_shutdown,
net/x25/af_x25.c +1 -1
@@ -1750,7 +1750,7 @@ static const struct proto_ops x25_proto_ops = { .socketpair = sock_no_socketpair, .accept = x25_accept, .getname = x25_getname, - .poll = datagram_poll, + .poll_mask = datagram_poll_mask, .ioctl = x25_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = compat_x25_ioctl,
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 16/31 net/dccp: convert to ->poll_mask
In reply to Christoph Hellwig--- net/dccp/dccp.h | 3 +-- net/dccp/ipv4.c | 2 +- net/dccp/ipv6.c | 2 +- net/dccp/proto.c | 13 ++----------- 4 files changed, 5 insertions(+), 15 deletions(-)
net/dccp/dccp.h +1 -2
@@ -316,8 +316,7 @@ int dccp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock, int flags, int *addr_len);void dccp_shutdown (struct sock *sk,int how);int inet_dccp_listen (struct socket *sock,int backlog); -__poll_t dccp_poll (struct file *file,struct socket *sock, -poll_table *wait); +__poll_t dccp_poll_mask (struct socket *sock,__poll_t events);int dccp_v4_connect (struct sock *sk,struct sockaddr *uaddr,int addr_len);void dccp_req_err (struct sock *sk,u64 seq);
net/dccp/ipv4.c +1 -1
@@ -984,7 +984,7 @@ static const struct proto_ops inet_dccp_ops = { .accept = inet_accept, .getname = inet_getname,/* FIXME: work on tcp_poll to rename it to inet_csk_poll */ - .poll = dccp_poll, + .poll_mask = dccp_poll_mask, .ioctl = inet_ioctl,/* FIXME: work on inet_listen to rename it to sock_common_listen */ .listen = inet_dccp_listen,
net/dccp/ipv6.c +1 -1
@@ -1070,7 +1070,7 @@ static const struct proto_ops inet6_dccp_ops = { .socketpair = sock_no_socketpair, .accept = inet_accept, .getname = inet6_getname, - .poll = dccp_poll, + .poll_mask = dccp_poll_mask, .ioctl = inet6_ioctl, .listen = inet_dccp_listen, .shutdown = inet_shutdown,
net/dccp/proto.c +2 -11
@@ -314,20 +314,11 @@ int dccp_disconnect(struct sock *sk, int flags)EXPORT_SYMBOL_GPL (dccp_disconnect); -/* -* Wait for a DCCP event. -* -* Note that we don't need to lock the socket, as the upper poll layers -* take care of normal races (between the test and the event) and we don't -* go look at any of the socket buffers directly. -*/ -__poll_t dccp_poll (struct file *file,struct socket *sock, -poll_table *wait) +__poll_t dccp_poll_mask (struct socket *sock,__poll_t events) {__poll_t mask;struct sock *sk = sock->sk; -sock_poll_wait (file,sk_sleep (sk), wait);if (sk->sk_state ==DCCP_LISTEN )return inet_csk_listen_poll (sk);
@@ -369,7 +360,7 @@ __poll_t dccp_poll(struct file *file, struct socket *sock,return mask; } -EXPORT_SYMBOL_GPL (dccp_poll); +EXPORT_SYMBOL_GPL (dccp_poll_mask);int dccp_ioctl (struct sock *sk,int cmd,unsigned long arg) {
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 17/31 net/atm: convert to ->poll_mask
In reply to Christoph Hellwig--- net/atm/common.c | 11 +++-------- net/atm/common.h | 2 +- net/atm/pvc.c | 2 +- net/atm/svc.c | 2 +- 4 files changed, 6 insertions(+), 11 deletions(-)
net/atm/common.c +3 -8
@@ -648,16 +648,11 @@ int vcc_sendmsg(struct socket *sock, struct msghdr *m, size_t size)return error; } -__poll_t vcc_poll (struct file *file,struct socket *sock,poll_table *wait) +__poll_t vcc_poll_mask (struct socket *sock,__poll_t events) {struct sock *sk = sock->sk; -struct atm_vcc *vcc; -__poll_t mask; - -sock_poll_wait (file,sk_sleep (sk), wait); - mask =0 ; - - vcc =ATM_SD (sock); +struct atm_vcc *vcc =ATM_SD (sock); +__poll_t mask =0 ;/* exceptional events */ if (sk->sk_err)
net/atm/common.h +1 -1
@@ -17,7 +17,7 @@ int vcc_connect(struct socket *sock, int itf, short vpi, int vci);int vcc_recvmsg (struct socket *sock,struct msghdr *msg,size_t size,int flags);int vcc_sendmsg (struct socket *sock,struct msghdr *m,size_t total_len); -__poll_t vcc_poll (struct file *file,struct socket *sock,poll_table *wait); +__poll_t vcc_poll_mask (struct socket *sock,__poll_t events);int vcc_ioctl (struct socket *sock,unsigned int cmd,unsigned long arg);int vcc_compat_ioctl (struct socket *sock,unsigned int cmd,unsigned long arg); int vcc_setsockopt(struct socket *sock, int level, int optname,
net/atm/pvc.c +1 -1
@@ -113,7 +113,7 @@ static const struct proto_ops pvc_proto_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = pvc_getname, - .poll = vcc_poll, + .poll_mask = vcc_poll_mask, .ioctl = vcc_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = vcc_compat_ioctl,
net/atm/svc.c +1 -1
@@ -636,7 +636,7 @@ static const struct proto_ops svc_proto_ops = { .socketpair = sock_no_socketpair, .accept = svc_accept, .getname = svc_getname, - .poll = vcc_poll, + .poll_mask = vcc_poll_mask, .ioctl = svc_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = svc_compat_ioctl,
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 18/31 net/vmw_vsock: convert to ->poll_mask
In reply to Christoph Hellwig--- net/vmw_vsock/af_vsock.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-)
net/vmw_vsock/af_vsock.c +6 -13
@@ -850,18 +850,11 @@ static int vsock_shutdown(struct socket *sock, int mode)return err; } -static __poll_t vsock_poll (struct file *file,struct socket *sock, -poll_table *wait) +static __poll_t vsock_poll_mask (struct socket *sock,__poll_t events) { -struct sock *sk; -__poll_t mask; -struct vsock_sock *vsk; - - sk = sock->sk; - vsk =vsock_sk (sk); - -poll_wait (file,sk_sleep (sk), wait); - mask =0 ; +struct sock *sk = sock->sk; +struct vsock_sock *vsk =vsock_sk (sk); +__poll_t mask =0 ;if (sk->sk_err)/* Signify that there has been an error on this socket. */
@@ -1091,7 +1084,7 @@ static const struct proto_ops vsock_dgram_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = vsock_getname, - .poll = vsock_poll, + .poll_mask = vsock_poll_mask, .ioctl = sock_no_ioctl, .listen = sock_no_listen, .shutdown = vsock_shutdown,
@@ -1849,7 +1842,7 @@ static const struct proto_ops vsock_stream_ops = { .socketpair = sock_no_socketpair, .accept = vsock_accept, .getname = vsock_getname, - .poll = vsock_poll, + .poll_mask = vsock_poll_mask, .ioctl = sock_no_ioctl, .listen = vsock_listen, .shutdown = vsock_shutdown,
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 19/31 net/tipc: convert to ->poll_mask
In reply to Christoph Hellwig--- net/tipc/socket.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-)
net/tipc/socket.c +5 -9
@@ -692,10 +692,9 @@ static int tipc_getname(struct socket *sock, struct sockaddr *uaddr, }/** -* tipc_poll - read and possibly block on pollmask +* tipc_poll - read pollmask * @file: file structure associated with the socket * @sock: socket for which to calculate the poll bits -* @wait: ??? * * Returns pollmask value *
@@ -709,15 +708,12 @@ static int tipc_getname(struct socket *sock, struct sockaddr *uaddr,* imply that the operation will succeed, merely that it should be performed * and will not block. */ -static __poll_t tipc_poll (struct file *file,struct socket *sock, -poll_table *wait) +static __poll_t tipc_poll_mask (struct socket *sock,__poll_t events) {struct sock *sk = sock->sk;struct tipc_sock *tsk =tipc_sk (sk);__poll_t revents =0 ; -sock_poll_wait (file,sk_sleep (sk), wait); -if (sk->sk_shutdown &RCV_SHUTDOWN ) revents |=EPOLLRDHUP |EPOLLIN |EPOLLRDNORM ;if (sk->sk_shutdown ==SHUTDOWN_MASK )
@@ -3027,7 +3023,7 @@ static const struct proto_ops msg_ops = { .socketpair = tipc_socketpair, .accept = sock_no_accept, .getname = tipc_getname, - .poll = tipc_poll, + .poll_mask = tipc_poll_mask, .ioctl = tipc_ioctl, .listen = sock_no_listen, .shutdown = tipc_shutdown,
@@ -3048,7 +3044,7 @@ static const struct proto_ops packet_ops = { .socketpair = tipc_socketpair, .accept = tipc_accept, .getname = tipc_getname, - .poll = tipc_poll, + .poll_mask = tipc_poll_mask, .ioctl = tipc_ioctl, .listen = tipc_listen, .shutdown = tipc_shutdown,
@@ -3069,7 +3065,7 @@ static const struct proto_ops stream_ops = { .socketpair = tipc_socketpair, .accept = tipc_accept, .getname = tipc_getname, - .poll = tipc_poll, + .poll_mask = tipc_poll_mask, .ioctl = tipc_ioctl, .listen = tipc_listen, .shutdown = tipc_shutdown,
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 20/31 net/sctp: convert to ->poll_mask
In reply to Christoph Hellwig--- include/net/sctp/sctp.h | 3 +-- net/sctp/ipv6.c | 2 +- net/sctp/protocol.c | 2 +- net/sctp/socket.c | 4 +--- 4 files changed, 4 insertions(+), 7 deletions(-)
include/net/sctp/sctp.h +1 -2
@@ -107,8 +107,7 @@ int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb);int sctp_inet_listen (struct socket *sock,int backlog);void sctp_write_space (struct sock *sk);void sctp_data_ready (struct sock *sk); -__poll_t sctp_poll (struct file *file,struct socket *sock, -poll_table *wait); +__poll_t sctp_poll_mask (struct socket *sock,__poll_t events);void sctp_sock_rfree (struct sk_buff *skb);void sctp_copy_sock (struct sock *newsk,struct sock *sk,struct sctp_association *asoc);
net/sctp/ipv6.c +1 -1
@@ -1007,7 +1007,7 @@ static const struct proto_ops inet6_seqpacket_ops = { .socketpair = sock_no_socketpair, .accept = inet_accept, .getname = sctp_getname, - .poll = sctp_poll, + .poll_mask = sctp_poll_mask, .ioctl = inet6_ioctl, .listen = sctp_inet_listen, .shutdown = inet_shutdown,
net/sctp/protocol.c +1 -1
@@ -1016,7 +1016,7 @@ static const struct proto_ops inet_seqpacket_ops = { .socketpair = sock_no_socketpair, .accept = inet_accept, .getname = inet_getname, /* Semantics are different. */ - .poll = sctp_poll, + .poll_mask = sctp_poll_mask, .ioctl = inet_ioctl, .listen = sctp_inet_listen, .shutdown = inet_shutdown, /* Looks harmless. */
net/sctp/socket.c +1 -3
@@ -7701,14 +7701,12 @@ int sctp_inet_listen(struct socket *sock, int backlog)* here, again, by modeling the current TCP/UDP code. We don't have * a good way to test with it yet. */ -__poll_t sctp_poll (struct file *file,struct socket *sock,poll_table *wait) +__poll_t sctp_poll_mask (struct socket *sock,__poll_t events) {struct sock *sk = sock->sk;struct sctp_sock *sp =sctp_sk (sk);__poll_t mask; -poll_wait (file,sk_sleep (sk), wait); -sock_rps_record_flow (sk);/* A TCP-style listening socket becomes readable when the accept queue
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 21/31 net/bluetooth: convert to ->poll_mask
In reply to Christoph Hellwig--- include/net/bluetooth/bluetooth.h | 2 +- net/bluetooth/af_bluetooth.c | 7 ++----- net/bluetooth/l2cap_sock.c | 2 +- net/bluetooth/rfcomm/sock.c | 2 +- net/bluetooth/sco.c | 2 +- 5 files changed, 6 insertions(+), 9 deletions(-)
include/net/bluetooth/bluetooth.h +1 -1
@@ -271,7 +271,7 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, int flags);int bt_sock_stream_recvmsg (struct socket *sock,struct msghdr *msg,size_t len,int flags); -__poll_t bt_sock_poll (struct file *file,struct socket *sock,poll_table *wait); +__poll_t bt_sock_poll_mask (struct socket *sock,__poll_t events);int bt_sock_ioctl (struct socket *sock,unsigned int cmd,unsigned long arg);int bt_sock_wait_state (struct sock *sk,int state,unsigned long timeo);int bt_sock_wait_ready (struct sock *sk,unsigned long flags);
net/bluetooth/af_bluetooth.c +2 -5
@@ -437,16 +437,13 @@ static inline __poll_t bt_accept_poll(struct sock *parent)return 0 ; } -__poll_t bt_sock_poll (struct file *file,struct socket *sock, -poll_table *wait) +__poll_t bt_sock_poll_mask (struct socket *sock,__poll_t events) {struct sock *sk = sock->sk;__poll_t mask =0 ;BT_DBG ("sock %p, sk %p" , sock, sk); -poll_wait (file,sk_sleep (sk), wait); -if (sk->sk_state ==BT_LISTEN )return bt_accept_poll (sk);
@@ -478,7 +475,7 @@ __poll_t bt_sock_poll(struct file *file, struct socket *sock,return mask; } -EXPORT_SYMBOL (bt_sock_poll); +EXPORT_SYMBOL (bt_sock_poll_mask);int bt_sock_ioctl (struct socket *sock,unsigned int cmd,unsigned long arg) {
net/bluetooth/l2cap_sock.c +1 -1
@@ -1653,7 +1653,7 @@ static const struct proto_ops l2cap_sock_ops = { .getname = l2cap_sock_getname, .sendmsg = l2cap_sock_sendmsg, .recvmsg = l2cap_sock_recvmsg, - .poll = bt_sock_poll, + .poll_mask = bt_sock_poll_mask, .ioctl = bt_sock_ioctl, .mmap = sock_no_mmap, .socketpair = sock_no_socketpair,
net/bluetooth/rfcomm/sock.c +1 -1
@@ -1049,7 +1049,7 @@ static const struct proto_ops rfcomm_sock_ops = { .setsockopt = rfcomm_sock_setsockopt, .getsockopt = rfcomm_sock_getsockopt, .ioctl = rfcomm_sock_ioctl, - .poll = bt_sock_poll, + .poll_mask = bt_sock_poll_mask, .socketpair = sock_no_socketpair, .mmap = sock_no_mmap };
net/bluetooth/sco.c +1 -1
@@ -1197,7 +1197,7 @@ static const struct proto_ops sco_sock_ops = { .getname = sco_sock_getname, .sendmsg = sco_sock_sendmsg, .recvmsg = sco_sock_recvmsg, - .poll = bt_sock_poll, + .poll_mask = bt_sock_poll_mask, .ioctl = bt_sock_ioctl, .mmap = sock_no_mmap, .socketpair = sock_no_socketpair,
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 22/31 net/caif: convert to ->poll_mask
In reply to Christoph Hellwig--- net/caif/caif_socket.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-)
net/caif/caif_socket.c +4 -8
@@ -934,15 +934,11 @@ static int caif_release(struct socket *sock) }/* Copied from af_unix.c:unix_poll(), added CAIF tx_flow handling */ -static __poll_t caif_poll (struct file *file, -struct socket *sock,poll_table *wait) +static __poll_t caif_poll_mask (struct socket *sock,__poll_t events) {struct sock *sk = sock->sk; -__poll_t mask; struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); - -sock_poll_wait (file,sk_sleep (sk), wait); - mask =0 ; +__poll_t mask =0 ;/* exceptional events? */ if (sk->sk_err)
@@ -976,7 +972,7 @@ static const struct proto_ops caif_seqpacket_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = sock_no_getname, - .poll = caif_poll, + .poll_mask = caif_poll_mask, .ioctl = sock_no_ioctl, .listen = sock_no_listen, .shutdown = sock_no_shutdown,
@@ -997,7 +993,7 @@ static const struct proto_ops caif_stream_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = sock_no_getname, - .poll = caif_poll, + .poll_mask = caif_poll_mask, .ioctl = sock_no_ioctl, .listen = sock_no_listen, .shutdown = sock_no_shutdown,
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 23/31 net/nfc: convert to ->poll_mask
In reply to Christoph Hellwig--- net/nfc/llcp_sock.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
net/nfc/llcp_sock.c +3 -6
@@ -548,16 +548,13 @@ static inline __poll_t llcp_accept_poll(struct sock *parent)return 0 ; } -static __poll_t llcp_sock_poll (struct file *file,struct socket *sock, -poll_table *wait) +static __poll_t llcp_sock_poll_mask (struct socket *sock,__poll_t events) {struct sock *sk = sock->sk;__poll_t mask =0 ;pr_debug ("%p\n" , sk); -sock_poll_wait (file,sk_sleep (sk), wait); -if (sk->sk_state ==LLCP_LISTEN )return llcp_accept_poll (sk);
@@ -899,7 +896,7 @@ static const struct proto_ops llcp_sock_ops = { .socketpair = sock_no_socketpair, .accept = llcp_sock_accept, .getname = llcp_sock_getname, - .poll = llcp_sock_poll, + .poll_mask = llcp_sock_poll_mask, .ioctl = sock_no_ioctl, .listen = llcp_sock_listen, .shutdown = sock_no_shutdown,
@@ -919,7 +916,7 @@ static const struct proto_ops llcp_rawsock_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = llcp_sock_getname, - .poll = llcp_sock_poll, + .poll_mask = llcp_sock_poll_mask, .ioctl = sock_no_ioctl, .listen = sock_no_listen, .shutdown = sock_no_shutdown,
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 24/31 net/phonet: convert to ->poll_mask
In reply to Christoph Hellwig--- net/phonet/socket.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
net/phonet/socket.c +2 -5
@@ -340,15 +340,12 @@ static int pn_socket_getname(struct socket *sock, struct sockaddr *addr,return sizeof (struct sockaddr_pn ); } -static __poll_t pn_socket_poll (struct file *file,struct socket *sock, -poll_table *wait) +static __poll_t pn_socket_poll_mask (struct socket *sock,__poll_t events) {struct sock *sk = sock->sk;struct pep_sock *pn =pep_sk (sk);__poll_t mask =0 ; -poll_wait (file,sk_sleep (sk), wait); -if (sk->sk_state ==TCP_CLOSE )return EPOLLERR ;if (!skb_queue_empty (&sk->sk_receive_queue))
@@ -473,7 +470,7 @@ const struct proto_ops phonet_stream_ops = { .socketpair = sock_no_socketpair, .accept = pn_socket_accept, .getname = pn_socket_getname, - .poll = pn_socket_poll, + .poll_mask = pn_socket_poll_mask, .ioctl = pn_socket_ioctl, .listen = pn_socket_listen, .shutdown = sock_no_shutdown,
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 25/31 net/iucv: convert to ->poll_mask
In reply to Christoph Hellwig--- include/net/iucv/af_iucv.h | 2 -- net/iucv/af_iucv.c | 7 ++----- 2 files changed, 2 insertions(+), 7 deletions(-)
include/net/iucv/af_iucv.h +0 -2
@@ -153,8 +153,6 @@ struct iucv_sock_list {atomic_t autobind_name; }; -__poll_t iucv_sock_poll (struct file *file,struct socket *sock, -poll_table *wait);void iucv_sock_link (struct iucv_sock_list *l,struct sock *s);void iucv_sock_unlink (struct iucv_sock_list *l,struct sock *s);void iucv_accept_enqueue (struct sock *parent,struct sock *sk);
net/iucv/af_iucv.c +2 -5
@@ -1488,14 +1488,11 @@ static inline __poll_t iucv_accept_poll(struct sock *parent)return 0 ; } -__poll_t iucv_sock_poll (struct file *file,struct socket *sock, -poll_table *wait) +static __poll_t iucv_sock_poll_mask (struct socket *sock,__poll_t events) {struct sock *sk = sock->sk;__poll_t mask =0 ; -sock_poll_wait (file,sk_sleep (sk), wait); -if (sk->sk_state ==IUCV_LISTEN )return iucv_accept_poll (sk);
@@ -2388,7 +2385,7 @@ static const struct proto_ops iucv_sock_ops = { .getname = iucv_sock_getname, .sendmsg = iucv_sock_sendmsg, .recvmsg = iucv_sock_recvmsg, - .poll = iucv_sock_poll, + .poll_mask = iucv_sock_poll_mask, .ioctl = sock_no_ioctl, .mmap = sock_no_mmap, .socketpair = sock_no_socketpair,
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 26/31 net/rxrpc: convert to ->poll_mask
In reply to Christoph Hellwig--- net/rxrpc/af_rxrpc.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
net/rxrpc/af_rxrpc.c +3 -7
@@ -734,15 +734,11 @@ static int rxrpc_getsockopt(struct socket *sock, int level, int optname,/* * permit an RxRPC socket to be polled */ -static __poll_t rxrpc_poll (struct file *file,struct socket *sock, -poll_table *wait) +static __poll_t rxrpc_poll_mask (struct socket *sock,__poll_t events) {struct sock *sk = sock->sk;struct rxrpc_sock *rx =rxrpc_sk (sk); -__poll_t mask; - -sock_poll_wait (file,sk_sleep (sk), wait); - mask =0 ; +__poll_t mask =0 ;/* the socket is readable if there are any messages waiting on the Rx * queue */
@@ -949,7 +945,7 @@ static const struct proto_ops rxrpc_rpc_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = sock_no_getname, - .poll = rxrpc_poll, + .poll_mask = rxrpc_poll_mask, .ioctl = sock_no_ioctl, .listen = rxrpc_listen, .shutdown = rxrpc_shutdown,
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 27/31 crypto: af_alg: convert to ->poll_mask
In reply to Christoph Hellwig--- crypto/af_alg.c | 13 +++---------- crypto/algif_aead.c | 4 ++-- crypto/algif_skcipher.c | 4 ++-- include/crypto/if_alg.h | 3 +-- 4 files changed, 8 insertions(+), 16 deletions(-)
crypto/af_alg.c +3 -10
@@ -1060,19 +1060,12 @@ void af_alg_async_cb(struct crypto_async_request *_req, int err) }EXPORT_SYMBOL_GPL (af_alg_async_cb); -/** -* af_alg_poll - poll system call handler -*/ -__poll_t af_alg_poll (struct file *file,struct socket *sock, -poll_table *wait) +__poll_t af_alg_poll_mask (struct socket *sock,__poll_t events) {struct sock *sk = sock->sk;struct alg_sock *ask =alg_sk (sk);struct af_alg_ctx *ctx = ask->private; -__poll_t mask; - -sock_poll_wait (file,sk_sleep (sk), wait); - mask =0 ; +__poll_t mask =0 ;if (!ctx->more || ctx->used) mask |=EPOLLIN |EPOLLRDNORM ;
@@ -1082,7 +1075,7 @@ __poll_t af_alg_poll(struct file *file, struct socket *sock,return mask; } -EXPORT_SYMBOL_GPL (af_alg_poll); +EXPORT_SYMBOL_GPL (af_alg_poll_mask);/** * af_alg_alloc_areq - allocate struct af_alg_async_req
crypto/algif_aead.c +2 -2
@@ -375,7 +375,7 @@ static struct proto_ops algif_aead_ops = { .sendmsg = aead_sendmsg, .sendpage = af_alg_sendpage, .recvmsg = aead_recvmsg, - .poll = af_alg_poll, + .poll_mask = af_alg_poll_mask, };static int aead_check_key (struct socket *sock)
@@ -471,7 +471,7 @@ static struct proto_ops algif_aead_ops_nokey = { .sendmsg = aead_sendmsg_nokey, .sendpage = aead_sendpage_nokey, .recvmsg = aead_recvmsg_nokey, - .poll = af_alg_poll, + .poll_mask = af_alg_poll_mask, };static void *aead_bind (const char *name,u32 type,u32 mask)
crypto/algif_skcipher.c +2 -2
@@ -205,7 +205,7 @@ static struct proto_ops algif_skcipher_ops = { .sendmsg = skcipher_sendmsg, .sendpage = af_alg_sendpage, .recvmsg = skcipher_recvmsg, - .poll = af_alg_poll, + .poll_mask = af_alg_poll_mask, };static int skcipher_check_key (struct socket *sock)
@@ -301,7 +301,7 @@ static struct proto_ops algif_skcipher_ops_nokey = { .sendmsg = skcipher_sendmsg_nokey, .sendpage = skcipher_sendpage_nokey, .recvmsg = skcipher_recvmsg_nokey, - .poll = af_alg_poll, + .poll_mask = af_alg_poll_mask, };static void *skcipher_bind (const char *name,u32 type,u32 mask)
include/crypto/if_alg.h +1 -2
@@ -245,8 +245,7 @@ ssize_t af_alg_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags);void af_alg_free_resources (struct af_alg_async_req *areq);void af_alg_async_cb (struct crypto_async_request *_req,int err); -__poll_t af_alg_poll (struct file *file,struct socket *sock, -poll_table *wait); +__poll_t af_alg_poll_mask (struct socket *sock,__poll_t events);struct af_alg_async_req *af_alg_alloc_areq (struct sock *sk,unsigned int areqlen); int af_alg_get_rsgl(struct sock *sk, struct msghdr *msg, int flags,
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 28/31 pipe: convert to ->poll_mask
In reply to Christoph Hellwig--- fs/pipe.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-)
fs/pipe.c +13 -9
@@ -509,19 +509,22 @@ static long pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } } -/* No kernel lock held - fine */ -static __poll_t -pipe_poll (struct file *filp,poll_table *wait) +static struct wait_queue_head * +pipe_get_poll_head (struct file *filp,__poll_t events) { -__poll_t mask;struct pipe_inode_info *pipe = filp->private_data; -int nrbufs; -poll_wait (filp, &pipe->wait, wait); +return &pipe->wait; +} + +/* No kernel lock held - fine */ +static __poll_t pipe_poll_mask (struct file *filp,__poll_t events) +{ +struct pipe_inode_info *pipe = filp->private_data; +int nrbufs = pipe->nrbufs; +__poll_t mask =0 ;/* Reading only -- no need for acquiring the semaphore. */ - nrbufs = pipe->nrbufs; - mask =0 ;if (filp->f_mode &FMODE_READ ) { mask = (nrbufs >0 ) ?EPOLLIN |EPOLLRDNORM :0 ;if (!pipe->writers && filp->f_version != pipe->w_counter)
@@ -1020,7 +1023,8 @@ const struct file_operations pipefifo_fops = { .llseek = no_llseek, .read_iter = pipe_read, .write_iter = pipe_write, - .poll = pipe_poll, + .get_poll_head = pipe_get_poll_head, + .poll_mask = pipe_poll_mask, .unlocked_ioctl = pipe_ioctl, .release = pipe_release, .fasync = pipe_fasync,
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 29/31 eventfd: switch to ->poll_mask
In reply to Christoph Hellwig--- fs/eventfd.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
fs/eventfd.c +11 -4
@@ -101,14 +101,20 @@ static int eventfd_release(struct inode *inode, struct file *file)return 0 ; } -static __poll_t eventfd_poll (struct file *file,poll_table *wait) +static struct wait_queue_head * +eventfd_get_poll_head (struct file *file,__poll_t events) +{ +struct eventfd_ctx *ctx = file->private_data; + +return &ctx->wqh; +} + +static __poll_t eventfd_poll_mask (struct file *file,__poll_t eventmask) {struct eventfd_ctx *ctx = file->private_data;__poll_t events =0 ;u64 count; -poll_wait (file, &ctx->wqh, wait); -/* * All writes to ctx->count occur within ctx->wqh.lock. This read * can be done outside ctx->wqh.lock because we know that poll_wait
@@ -305,7 +311,8 @@ static const struct file_operations eventfd_fops = { .show_fdinfo = eventfd_show_fdinfo, #endif .release = eventfd_release, - .poll = eventfd_poll, + .get_poll_head = eventfd_get_poll_head, + .poll_mask = eventfd_poll_mask, .read = eventfd_read, .write = eventfd_write, .llseek = noop_llseek,
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 30/31 timerfd: convert to ->poll_mask
In reply to Christoph Hellwig--- fs/timerfd.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-)
fs/timerfd.c +11 -11
@@ -226,21 +226,20 @@ static int timerfd_release(struct inode *inode, struct file *file)kfree_rcu (ctx, rcu);return 0 ; } - -static __poll_t timerfd_poll (struct file *file,poll_table *wait) + +static struct wait_queue_head *timerfd_get_poll_head (struct file *file, +__poll_t eventmask) {struct timerfd_ctx *ctx = file->private_data; -__poll_t events =0 ; -unsigned long flags; -poll_wait (file, &ctx->wqh, wait); +return &ctx->wqh; +} -spin_lock_irqsave (&ctx->wqh.lock, flags); -if (ctx->ticks) - events |=EPOLLIN ; -spin_unlock_irqrestore (&ctx->wqh.lock, flags); +static __poll_t timerfd_poll_mask (struct file *file,__poll_t eventmask) +{ +struct timerfd_ctx *ctx = file->private_data; -return events; +return ctx->ticks ?EPOLLIN :0 ; } static ssize_t timerfd_read(struct file *file, char __user *buf, size_t count,
@@ -364,7 +363,8 @@ static long timerfd_ioctl(struct file *file, unsigned int cmd, unsigned long argstatic const struct file_operations timerfd_fops = { .release = timerfd_release, - .poll = timerfd_poll, + .get_poll_head = timerfd_get_poll_head, + .poll_mask = timerfd_poll_mask, .read = timerfd_read, .llseek = noop_llseek, .show_fdinfo = timerfd_show,
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
Re: [PATCH 30/31] timerfd: convert to ->poll_mask
Hello!
Quoted 10 lines · Christoph Hellwig
Signed-off-by Christoph Hellwig <[email protected]>--- fs/timerfd.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-)fs/timerfd.c +0
-0
fs/timerfd.c static int timerfd_release(struct inode *inode, struct file *file) · line 229
Quoted 6 lines
fs/timerfd.c +1
-2@@ -226,21 +226,20 @@ static int timerfd_release(struct inode *inode, struct file *file)kfree_rcu (ctx, rcu);return 0 ; } - -static __poll_t timerfd_poll (struct file *file,poll_table *wait) +
Stray tab detected! :-)
Quoted 14 lines
fs/timerfd.c +4
-6+static struct wait_queue_head *timerfd_get_poll_head (struct file *file, +__poll_t eventmask) {struct timerfd_ctx *ctx = file->private_data; -__poll_t events =0 ; -unsigned long flags; -poll_wait (file, &ctx->wqh, wait); +return &ctx->wqh; +} -spin_lock_irqsave (&ctx->wqh.lock, flags); -if (ctx->ticks) - events |=EPOLLIN ;
fs/timerfd.c static int timerfd_release(struct inode *inode, struct file *file) · line 245
Quoted 10 lines
fs/timerfd.c +4
-2-spin_unlock_irqrestore (&ctx->wqh.lock, flags); +static __poll_t timerfd_poll_mask (struct file *file,__poll_t eventmask) +{ +struct timerfd_ctx *ctx = file->private_data; -return events; +return ctx->ticks ?EPOLLIN :0 ; } static ssize_t timerfd_read(struct file *file, char __user *buf, size_t count,
[...]
MBR, Sergei
--
To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"[email protected]">[email protected]</a>
PATCH 31/31 random: convert to ->poll_mask
In reply to Christoph HellwigThe big change is that random_read_wait and random_write_wait are merged into a single waitqueue that uses keyed wakeups. Because wait_event_* doesn't know about that this will lead to occassional spurious wakeups in _random_read and add_hwgenerator_randomness, but wait_event_* is designed to handle these and were are not in a a hot path there.
--- drivers/char/random.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-)
drivers/char/random.c +16 -13
@@ -402,8 +402,7 @@ static struct poolinfo {/* * Static global variables */ -static DECLARE_WAIT_QUEUE_HEAD (random_read_wait); -static DECLARE_WAIT_QUEUE_HEAD (random_write_wait); +static DECLARE_WAIT_QUEUE_HEAD (random_wait);static struct fasync_struct *fasync;static DEFINE_SPINLOCK (random_ready_list_lock);
@@ -722,8 +721,8 @@ static void credit_entropy_bits(struct entropy_store *r, int nbits)/* should we wake readers? */ if (entropy_bits >= random_read_wakeup_bits && -wq_has_sleeper (&random_read_wait)) { -wake_up_interruptible (&random_read_wait); +wq_has_sleeper (&random_wait)) { +wake_up_interruptible_poll (&random_wait,POLLIN );kill_fasync (&fasync,SIGIO ,POLL_IN ); }/* If the input pool is getting full, send some
@@ -1397,7 +1396,7 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,trace_debit_entropy (r->name,8 * ibytes);if (ibytes && (r->entropy_count >>ENTROPY_SHIFT ) < random_write_wakeup_bits) { -wake_up_interruptible (&random_write_wait); +wake_up_interruptible_poll (&random_wait,POLLOUT );kill_fasync (&fasync,SIGIO ,POLL_OUT ); }
@@ -1839,7 +1838,7 @@ _random_read(int nonblock, char __user *buf, size_t nbytes)if (nonblock)return -EAGAIN ; -wait_event_interruptible (random_read_wait, +wait_event_interruptible (random_wait,ENTROPY_BITS (&input_pool) >= random_read_wakeup_bits);if (signal_pending (current))
@@ -1876,14 +1875,17 @@ urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)return ret; } +static struct wait_queue_head * +random_get_poll_head (struct file *file,__poll_t events) +{ +return &random_wait; +} +static __poll_t -random_poll (struct file *file,poll_table * wait) +random_poll_mask (struct file *file,__poll_t events) { -__poll_t mask; +__poll_t mask =0 ; -poll_wait (file, &random_read_wait, wait); -poll_wait (file, &random_write_wait, wait); - mask =0 ;if (ENTROPY_BITS (&input_pool) >= random_read_wakeup_bits) mask |=EPOLLIN |EPOLLRDNORM ;if (ENTROPY_BITS (&input_pool) < random_write_wakeup_bits)
@@ -1990,7 +1992,8 @@ static int random_fasync(int fd, struct file *filp, int on)const struct file_operations random_fops = { .read = random_read, .write = random_write, - .poll = random_poll, + .get_poll_head = random_get_poll_head, + .poll_mask = random_poll_mask, .unlocked_ioctl = random_ioctl, .fasync = random_fasync, .llseek = noop_llseek,
@@ -2323,7 +2326,7 @@ void add_hwgenerator_randomness(const char *buffer, size_t count,* We'll be woken up again once below random_write_wakeup_thresh, * or when the calling thread is about to terminate. */ -wait_event_interruptible (random_write_wait,kthread_should_stop () || +wait_event_interruptible (random_wait,kthread_should_stop () ||ENTROPY_BITS (&input_pool) <= random_write_wakeup_bits);mix_pool_bytes (poolp, buffer, count);credit_entropy_bits (poolp, entropy);
Signature · 7 lines
2.17.0 -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"[email protected]">[email protected]</a>
Al Viro
maintainerQuoted 11 lines · Christoph Hellwig
Hi all,
this series adds support for the
IOCB_CMD_POLLoperation to poll for the readyness of file descriptors using the aio subsystem. The API is based on patches that existed in RHAS2.1 and RHEL3, which means it already is supported by libaio. To implement the poll support efficiently new methods to poll are introduced in structfile_operations:get_poll_headandpoll_mask. The first one returns await_queue_headto wait on (lifetime is bound by the file), and the second does a non-blocking check for the POLL* events. This allows aio poll to work without any additional context switches, unlike epoll.
I can live with that, modulo bug in #8 (see reply to that one). There's some nitpicking, but that can be dealt with in followups.