[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20171128100503.580847211@linuxfoundation.org>
Date: Tue, 28 Nov 2017 11:22:16 +0100
From: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To: linux-kernel@...r.kernel.org
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
stable@...r.kernel.org, Michal Kubecek <mkubecek@...e.cz>,
Stefan Hajnoczi <stefanha@...hat.com>,
Jorgen Hansen <jhansen@...are.com>,
"Michael S. Tsirkin" <mst@...hat.com>,
Claudio Imbrenda <imbrenda@...ux.vnet.ibm.com>,
Cong Wang <xiyou.wangcong@...il.com>,
"David S. Miller" <davem@...emloft.net>
Subject: [PATCH 4.4 07/96] vsock: use new wait API for vsock_stream_sendmsg()
4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: WANG Cong <xiyou.wangcong@...il.com>
commit 499fde662f1957e3cb8d192a94a099ebe19c714b upstream.
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 commit
d9dc8b0f8b4e ("net: fix sleeping for sk_wait_event()").
Reported-by: Michal Kubecek <mkubecek@...e.cz>
Cc: Stefan Hajnoczi <stefanha@...hat.com>
Cc: Jorgen Hansen <jhansen@...are.com>
Cc: "Michael S. Tsirkin" <mst@...hat.com>
Cc: Claudio Imbrenda <imbrenda@...ux.vnet.ibm.com>
Signed-off-by: Cong Wang <xiyou.wangcong@...il.com>
Reviewed-by: Stefan Hajnoczi <stefanha@...hat.com>
Signed-off-by: David S. Miller <davem@...emloft.net>
Cc: "Jorgen S. Hansen" <jhansen@...are.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
---
net/vmw_vsock/af_vsock.c | 21 ++++++++-------------
1 file changed, 8 insertions(+), 13 deletions(-)
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -1512,8 +1512,7 @@ static int vsock_stream_sendmsg(struct s
long timeout;
int err;
struct vsock_transport_send_notify_data send_data;
-
- DEFINE_WAIT(wait);
+ DEFINE_WAIT_FUNC(wait, woken_wake_function);
sk = sock->sk;
vsk = vsock_sk(sk);
@@ -1556,11 +1555,10 @@ static int vsock_stream_sendmsg(struct s
if (err < 0)
goto out;
-
while (total_written < len) {
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 &&
sk->sk_err == 0 &&
!(sk->sk_shutdown & SEND_SHUTDOWN) &&
@@ -1569,33 +1567,30 @@ static int vsock_stream_sendmsg(struct s
/* Don't wait for non-blocking sockets. */
if (timeout == 0) {
err = -EAGAIN;
- finish_wait(sk_sleep(sk), &wait);
+ remove_wait_queue(sk_sleep(sk), &wait);
goto out_err;
}
err = transport->notify_send_pre_block(vsk, &send_data);
if (err < 0) {
- finish_wait(sk_sleep(sk), &wait);
+ remove_wait_queue(sk_sleep(sk), &wait);
goto out_err;
}
release_sock(sk);
- timeout = schedule_timeout(timeout);
+ timeout = wait_woken(&wait, TASK_INTERRUPTIBLE, timeout);
lock_sock(sk);
if (signal_pending(current)) {
err = sock_intr_errno(timeout);
- finish_wait(sk_sleep(sk), &wait);
+ remove_wait_queue(sk_sleep(sk), &wait);
goto out_err;
} else if (timeout == 0) {
err = -EAGAIN;
- finish_wait(sk_sleep(sk), &wait);
+ remove_wait_queue(sk_sleep(sk), &wait);
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
* conditional since we need to check before and after
Powered by blists - more mailing lists