mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 04:48:04 +09:00
vsock: use new wait API for vsock_stream_sendmsg()
commit499fde662fupstream. As reported by Michal, vsock_stream_sendmsg() could still sleep at vsock_stream_has_space() after prepare_to_wait(): vsock_stream_has_space vmci_transport_stream_has_space vmci_qpair_produce_free_space qp_lock qp_acquire_queue_mutex mutex_lock Just switch to the new wait API like we did for commitd9dc8b0f8b("net: fix sleeping for sk_wait_event()"). Reported-by: Michal Kubecek <mkubecek@suse.cz> Cc: Stefan Hajnoczi <stefanha@redhat.com> Cc: Jorgen Hansen <jhansen@vmware.com> Cc: "Michael S. Tsirkin" <mst@redhat.com> Cc: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net> Cc: "Jorgen S. Hansen" <jhansen@vmware.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
df24d6c224
commit
3223ea1291
@@ -1512,8 +1512,7 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
|
|||||||
long timeout;
|
long timeout;
|
||||||
int err;
|
int err;
|
||||||
struct vsock_transport_send_notify_data send_data;
|
struct vsock_transport_send_notify_data send_data;
|
||||||
|
DEFINE_WAIT_FUNC(wait, woken_wake_function);
|
||||||
DEFINE_WAIT(wait);
|
|
||||||
|
|
||||||
sk = sock->sk;
|
sk = sock->sk;
|
||||||
vsk = vsock_sk(sk);
|
vsk = vsock_sk(sk);
|
||||||
@@ -1556,11 +1555,10 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
|
|||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
|
||||||
while (total_written < len) {
|
while (total_written < len) {
|
||||||
ssize_t written;
|
ssize_t written;
|
||||||
|
|
||||||
prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
|
add_wait_queue(sk_sleep(sk), &wait);
|
||||||
while (vsock_stream_has_space(vsk) == 0 &&
|
while (vsock_stream_has_space(vsk) == 0 &&
|
||||||
sk->sk_err == 0 &&
|
sk->sk_err == 0 &&
|
||||||
!(sk->sk_shutdown & SEND_SHUTDOWN) &&
|
!(sk->sk_shutdown & SEND_SHUTDOWN) &&
|
||||||
@@ -1569,33 +1567,30 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
|
|||||||
/* Don't wait for non-blocking sockets. */
|
/* Don't wait for non-blocking sockets. */
|
||||||
if (timeout == 0) {
|
if (timeout == 0) {
|
||||||
err = -EAGAIN;
|
err = -EAGAIN;
|
||||||
finish_wait(sk_sleep(sk), &wait);
|
remove_wait_queue(sk_sleep(sk), &wait);
|
||||||
goto out_err;
|
goto out_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = transport->notify_send_pre_block(vsk, &send_data);
|
err = transport->notify_send_pre_block(vsk, &send_data);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
finish_wait(sk_sleep(sk), &wait);
|
remove_wait_queue(sk_sleep(sk), &wait);
|
||||||
goto out_err;
|
goto out_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
release_sock(sk);
|
release_sock(sk);
|
||||||
timeout = schedule_timeout(timeout);
|
timeout = wait_woken(&wait, TASK_INTERRUPTIBLE, timeout);
|
||||||
lock_sock(sk);
|
lock_sock(sk);
|
||||||
if (signal_pending(current)) {
|
if (signal_pending(current)) {
|
||||||
err = sock_intr_errno(timeout);
|
err = sock_intr_errno(timeout);
|
||||||
finish_wait(sk_sleep(sk), &wait);
|
remove_wait_queue(sk_sleep(sk), &wait);
|
||||||
goto out_err;
|
goto out_err;
|
||||||
} else if (timeout == 0) {
|
} else if (timeout == 0) {
|
||||||
err = -EAGAIN;
|
err = -EAGAIN;
|
||||||
finish_wait(sk_sleep(sk), &wait);
|
remove_wait_queue(sk_sleep(sk), &wait);
|
||||||
goto out_err;
|
goto out_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
prepare_to_wait(sk_sleep(sk), &wait,
|
|
||||||
TASK_INTERRUPTIBLE);
|
|
||||||
}
|
}
|
||||||
finish_wait(sk_sleep(sk), &wait);
|
remove_wait_queue(sk_sleep(sk), &wait);
|
||||||
|
|
||||||
/* These checks occur both as part of and after the loop
|
/* These checks occur both as part of and after the loop
|
||||||
* conditional since we need to check before and after
|
* conditional since we need to check before and after
|
||||||
|
|||||||
Reference in New Issue
Block a user