lkml.org 
[lkml]   [2021]   [Mar]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[RFC PATCH v6 05/22] af_vsock: separate wait space loop
    Date
    This moves loop that waits for space on send to separate function,
    because it will be used for SEQ_BEGIN/SEQ_END sending before and
    after data transmission. Waiting for SEQ_BEGIN/SEQ_END is needed
    because such packets carries SEQPACKET header that couldn't be
    fragmented by credit mechanism, so to avoid it, sender waits until
    enough space will be ready.

    Signed-off-by: Arseny Krasnov <arseny.krasnov@kaspersky.com>
    Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
    ---
    include/net/af_vsock.h | 2 +
    net/vmw_vsock/af_vsock.c | 99 +++++++++++++++++++++++++---------------
    2 files changed, 63 insertions(+), 38 deletions(-)

    diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h
    index 5ad7ee7f78fd..a8c4039e40cf 100644
    --- a/include/net/af_vsock.h
    +++ b/include/net/af_vsock.h
    @@ -205,6 +205,8 @@ void vsock_remove_sock(struct vsock_sock *vsk);
    void vsock_for_each_connected_socket(void (*fn)(struct sock *sk));
    int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk);
    bool vsock_find_cid(unsigned int cid);
    +int vsock_wait_space(struct sock *sk, size_t space, int flags,
    + struct vsock_transport_send_notify_data *send_data);

    /**** TAP ****/

    diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
    index ac2f69362f2e..5bf64a3e678a 100644
    --- a/net/vmw_vsock/af_vsock.c
    +++ b/net/vmw_vsock/af_vsock.c
    @@ -1692,6 +1692,65 @@ static int vsock_connectible_getsockopt(struct socket *sock,
    return 0;
    }

    +int vsock_wait_space(struct sock *sk, size_t space, int flags,
    + struct vsock_transport_send_notify_data *send_data)
    +{
    + const struct vsock_transport *transport;
    + struct vsock_sock *vsk;
    + long timeout;
    + int err;
    +
    + DEFINE_WAIT_FUNC(wait, woken_wake_function);
    +
    + vsk = vsock_sk(sk);
    + transport = vsk->transport;
    + timeout = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
    + err = 0;
    +
    + add_wait_queue(sk_sleep(sk), &wait);
    +
    + while (vsock_stream_has_space(vsk) < space &&
    + sk->sk_err == 0 &&
    + !(sk->sk_shutdown & SEND_SHUTDOWN) &&
    + !(vsk->peer_shutdown & RCV_SHUTDOWN)) {
    +
    + /* Don't wait for non-blocking sockets. */
    + if (timeout == 0) {
    + err = -EAGAIN;
    + goto out_err;
    + }
    +
    + if (send_data) {
    + err = transport->notify_send_pre_block(vsk, send_data);
    + if (err < 0)
    + goto out_err;
    + }
    +
    + release_sock(sk);
    + timeout = wait_woken(&wait, TASK_INTERRUPTIBLE, timeout);
    + lock_sock(sk);
    + if (signal_pending(current)) {
    + err = sock_intr_errno(timeout);
    + goto out_err;
    + } else if (timeout == 0) {
    + err = -EAGAIN;
    + goto out_err;
    + }
    + }
    +
    + if (sk->sk_err) {
    + err = -sk->sk_err;
    + } else if ((sk->sk_shutdown & SEND_SHUTDOWN) ||
    + (vsk->peer_shutdown & RCV_SHUTDOWN)) {
    + err = -EPIPE;
    + }
    +
    +out_err:
    + remove_wait_queue(sk_sleep(sk), &wait);
    + return err;
    +}
    +EXPORT_SYMBOL_GPL(vsock_wait_space);
    +
    static int vsock_connectible_sendmsg(struct socket *sock, struct msghdr *msg,
    size_t len)
    {
    @@ -1699,10 +1758,8 @@ static int vsock_connectible_sendmsg(struct socket *sock, struct msghdr *msg,
    struct vsock_sock *vsk;
    const struct vsock_transport *transport;
    ssize_t total_written;
    - long timeout;
    int err;
    struct vsock_transport_send_notify_data send_data;
    - DEFINE_WAIT_FUNC(wait, woken_wake_function);

    sk = sock->sk;
    vsk = vsock_sk(sk);
    @@ -1740,9 +1797,6 @@ static int vsock_connectible_sendmsg(struct socket *sock, struct msghdr *msg,
    goto out;
    }

    - /* Wait for room in the produce queue to enqueue our user's data. */
    - timeout = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
    -
    err = transport->notify_send_init(vsk, &send_data);
    if (err < 0)
    goto out;
    @@ -1750,39 +1804,8 @@ static int vsock_connectible_sendmsg(struct socket *sock, struct msghdr *msg,
    while (total_written < len) {
    ssize_t written;

    - add_wait_queue(sk_sleep(sk), &wait);
    - while (vsock_stream_has_space(vsk) == 0 &&
    - sk->sk_err == 0 &&
    - !(sk->sk_shutdown & SEND_SHUTDOWN) &&
    - !(vsk->peer_shutdown & RCV_SHUTDOWN)) {
    -
    - /* Don't wait for non-blocking sockets. */
    - if (timeout == 0) {
    - err = -EAGAIN;
    - remove_wait_queue(sk_sleep(sk), &wait);
    - goto out_err;
    - }
    -
    - err = transport->notify_send_pre_block(vsk, &send_data);
    - if (err < 0) {
    - remove_wait_queue(sk_sleep(sk), &wait);
    - goto out_err;
    - }
    -
    - release_sock(sk);
    - timeout = wait_woken(&wait, TASK_INTERRUPTIBLE, timeout);
    - lock_sock(sk);
    - if (signal_pending(current)) {
    - err = sock_intr_errno(timeout);
    - remove_wait_queue(sk_sleep(sk), &wait);
    - goto out_err;
    - } else if (timeout == 0) {
    - err = -EAGAIN;
    - remove_wait_queue(sk_sleep(sk), &wait);
    - goto out_err;
    - }
    - }
    - remove_wait_queue(sk_sleep(sk), &wait);
    + if (vsock_wait_space(sk, 1, msg->msg_flags, &send_data))
    + goto out_err;

    /* These checks occur both as part of and after the loop
    * conditional since we need to check before and after
    --
    2.25.1
    \
     
     \ /
      Last update: 2021-03-07 19:01    [W:4.225 / U:1.380 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site