lkml.org 
[lkml]   [2018]   [Mar]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 16/36] net: add support for ->poll_mask in proto_ops
    Date
    The socket file operations still implement ->poll until all protocols are
    switched over.

    Signed-off-by: Christoph Hellwig <hch@lst.de>
    ---
    include/linux/net.h | 3 +++
    net/socket.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++-----
    2 files changed, 49 insertions(+), 5 deletions(-)

    diff --git a/include/linux/net.h b/include/linux/net.h
    index 91216b16feb7..ce3d4dacb51e 100644
    --- a/include/linux/net.h
    +++ b/include/linux/net.h
    @@ -147,6 +147,9 @@ struct proto_ops {
    int (*getname) (struct socket *sock,
    struct sockaddr *addr,
    int *sockaddr_len, int peer);
    + struct wait_queue_head *(*get_poll_head)(struct socket *sock,
    + __poll_t events);
    + __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,
    diff --git a/net/socket.c b/net/socket.c
    index 3f859a07641a..ceb69ddcd7bd 100644
    --- a/net/socket.c
    +++ b/net/socket.c
    @@ -118,8 +118,10 @@ static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from);
    static int sock_mmap(struct file *file, struct vm_area_struct *vma);

    static int sock_close(struct inode *inode, struct file *file);
    -static __poll_t sock_poll(struct file *file,
    - struct poll_table_struct *wait);
    +static struct wait_queue_head *sock_get_poll_head(struct file *file,
    + __poll_t events);
    +static __poll_t sock_poll_mask(struct file *file, __poll_t);
    +static __poll_t sock_poll(struct file *file, struct poll_table_struct *wait);
    static long sock_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
    #ifdef CONFIG_COMPAT
    static long compat_sock_ioctl(struct file *file,
    @@ -142,6 +144,8 @@ static const struct file_operations socket_file_ops = {
    .llseek = no_llseek,
    .read_iter = sock_read_iter,
    .write_iter = sock_write_iter,
    + .get_poll_head = sock_get_poll_head,
    + .poll_mask = sock_poll_mask,
    .poll = sock_poll,
    .unlocked_ioctl = sock_ioctl,
    #ifdef CONFIG_COMPAT
    @@ -1114,14 +1118,51 @@ int sock_create_lite(int family, int type, int protocol, struct socket **res)
    }
    EXPORT_SYMBOL(sock_create_lite);

    +static struct wait_queue_head *sock_get_poll_head(struct file *file,
    + __poll_t events)
    +{
    + struct socket *sock = file->private_data;
    +
    + if (!sock->ops->poll_mask)
    + return NULL;
    + if (sock->ops->get_poll_head)
    + return sock->ops->get_poll_head(sock, events);
    +
    + sock_poll_busy_loop(sock, events);
    + return sk_sleep(sock->sk);
    +}
    +
    +static __poll_t sock_poll_mask(struct file *file, __poll_t events)
    +{
    + struct socket *sock = file->private_data;
    +
    + /*
    + * We need to be sure we are in sync with the socket flags modification.
    + *
    + * This memory barrier is paired in the wq_has_sleeper.
    + */
    + smp_mb();
    +
    + /* this socket can poll_ll so tell the system call */
    + return sock->ops->poll_mask(sock, events) |
    + (sk_can_busy_loop(sock->sk) ? POLL_BUSY_LOOP : 0);
    +}
    +
    /* No kernel lock held - perfect */
    static __poll_t sock_poll(struct file *file, poll_table *wait)
    {
    struct socket *sock = file->private_data;
    - __poll_t events = poll_requested_events(wait);
    + __poll_t events = poll_requested_events(wait), mask = 0;

    - sock_poll_busy_loop(sock, events);
    - return sock->ops->poll(file, sock, wait) | sock_poll_busy_flag(sock);
    + if (sock->ops->poll) {
    + sock_poll_busy_loop(sock, events);
    + mask = sock->ops->poll(file, sock, wait);
    + } else if (sock->ops->poll_mask) {
    + sock_poll_wait(file, sock_get_poll_head(file, events), wait);
    + mask = sock->ops->poll_mask(sock, events);
    + }
    +
    + return mask | sock_poll_busy_flag(sock);
    }

    static int sock_mmap(struct file *file, struct vm_area_struct *vma)
    --
    2.14.2
    \
     
     \ /
      Last update: 2018-03-05 22:36    [W:2.374 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site