All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv2] vsock: Fix blocking ops call in prepare_to_wait
@ 2016-02-04 18:50 Laura Abbott
  2016-02-13 10:59 ` David Miller
  0 siblings, 1 reply; 6+ messages in thread
From: Laura Abbott @ 2016-02-04 18:50 UTC (permalink / raw)
  To: David S. Miller, Aditya Asarwade, Thomas Hellstrom, Jorgen Hansen
  Cc: Laura Abbott, netdev, linux-kernel

We receoved a bug report from someone using vmware:

WARNING: CPU: 3 PID: 660 at kernel/sched/core.c:7389
__might_sleep+0x7d/0x90()
do not call blocking ops when !TASK_RUNNING; state=1 set at
[<ffffffff810fa68d>] prepare_to_wait+0x2d/0x90
Modules linked in: vmw_vsock_vmci_transport vsock snd_seq_midi
snd_seq_midi_event snd_ens1371 iosf_mbi gameport snd_rawmidi
snd_ac97_codec ac97_bus snd_seq coretemp snd_seq_device snd_pcm
snd_timer snd soundcore ppdev crct10dif_pclmul crc32_pclmul
ghash_clmulni_intel vmw_vmci vmw_balloon i2c_piix4 shpchp parport_pc
parport acpi_cpufreq nfsd auth_rpcgss nfs_acl lockd grace sunrpc btrfs
xor raid6_pq 8021q garp stp llc mrp crc32c_intel serio_raw mptspi vmwgfx
drm_kms_helper ttm drm scsi_transport_spi mptscsih e1000 ata_generic
mptbase pata_acpi
CPU: 3 PID: 660 Comm: vmtoolsd Not tainted
4.2.0-0.rc1.git3.1.fc23.x86_64 #1
Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop
Reference Platform, BIOS 6.00 05/20/2014
 0000000000000000 0000000049e617f3 ffff88006ac37ac8 ffffffff818641f5
 0000000000000000 ffff88006ac37b20 ffff88006ac37b08 ffffffff810ab446
 ffff880068009f40 ffffffff81c63bc0 0000000000000061 0000000000000000
Call Trace:
 [<ffffffff818641f5>] dump_stack+0x4c/0x65
 [<ffffffff810ab446>] warn_slowpath_common+0x86/0xc0
 [<ffffffff810ab4d5>] warn_slowpath_fmt+0x55/0x70
 [<ffffffff8112551d>] ? debug_lockdep_rcu_enabled+0x1d/0x20
 [<ffffffff810fa68d>] ? prepare_to_wait+0x2d/0x90
 [<ffffffff810fa68d>] ? prepare_to_wait+0x2d/0x90
 [<ffffffff810da2bd>] __might_sleep+0x7d/0x90
 [<ffffffff812163b3>] __might_fault+0x43/0xa0
 [<ffffffff81430477>] copy_from_iter+0x87/0x2a0
 [<ffffffffa039460a>] __qp_memcpy_to_queue+0x9a/0x1b0 [vmw_vmci]
 [<ffffffffa0394740>] ? qp_memcpy_to_queue+0x20/0x20 [vmw_vmci]
 [<ffffffffa0394757>] qp_memcpy_to_queue_iov+0x17/0x20 [vmw_vmci]
 [<ffffffffa0394d50>] qp_enqueue_locked+0xa0/0x140 [vmw_vmci]
 [<ffffffffa039593f>] vmci_qpair_enquev+0x4f/0xd0 [vmw_vmci]
 [<ffffffffa04847bb>] vmci_transport_stream_enqueue+0x1b/0x20
[vmw_vsock_vmci_transport]
 [<ffffffffa047ae05>] vsock_stream_sendmsg+0x2c5/0x320 [vsock]
 [<ffffffff810fabd0>] ? wake_atomic_t_function+0x70/0x70
 [<ffffffff81702af8>] sock_sendmsg+0x38/0x50
 [<ffffffff81702ff4>] SYSC_sendto+0x104/0x190
 [<ffffffff8126e25a>] ? vfs_read+0x8a/0x140
 [<ffffffff817042ee>] SyS_sendto+0xe/0x10
 [<ffffffff8186d9ae>] entry_SYSCALL_64_fastpath+0x12/0x76

transport->stream_enqueue may call copy_to_user so it should
not be called inside a prepare_to_wait. Narrow the scope of
the prepare_to_wait to avoid the bad call. This also applies
to vsock_stream_recvmsg as well.

Reported-by: Vinson Lee <vlee@freedesktop.org>
Tested-by: Vinson Lee <vlee@freedesktop.org>
Signed-off-by: Laura Abbott <labbott@fedoraproject.org>
---
v2: fix same issue in recvmsg path as well.
---
 net/vmw_vsock/af_vsock.c | 19 ++++++-------------
 1 file changed, 6 insertions(+), 13 deletions(-)

diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 7fd1220..bbe65dc 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -1557,8 +1557,6 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
 	if (err < 0)
 		goto out;
 
-	prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
-
 	while (total_written < len) {
 		ssize_t written;
 
@@ -1578,7 +1576,9 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
 				goto out_wait;
 
 			release_sock(sk);
+			prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
 			timeout = schedule_timeout(timeout);
+			finish_wait(sk_sleep(sk), &wait);
 			lock_sock(sk);
 			if (signal_pending(current)) {
 				err = sock_intr_errno(timeout);
@@ -1588,8 +1588,6 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
 				goto out_wait;
 			}
 
-			prepare_to_wait(sk_sleep(sk), &wait,
-					TASK_INTERRUPTIBLE);
 		}
 
 		/* These checks occur both as part of and after the loop
@@ -1635,7 +1633,6 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
 out_wait:
 	if (total_written > 0)
 		err = total_written;
-	finish_wait(sk_sleep(sk), &wait);
 out:
 	release_sock(sk);
 	return err;
@@ -1716,7 +1713,6 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 	if (err < 0)
 		goto out;
 
-	prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
 
 	while (1) {
 		s64 ready = vsock_stream_has_data(vsk);
@@ -1727,7 +1723,7 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 			 */
 
 			err = -ENOMEM;
-			goto out_wait;
+			goto out;
 		} else if (ready > 0) {
 			ssize_t read;
 
@@ -1750,7 +1746,7 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 					vsk, target, read,
 					!(flags & MSG_PEEK), &recv_data);
 			if (err < 0)
-				goto out_wait;
+				goto out;
 
 			if (read >= target || flags & MSG_PEEK)
 				break;
@@ -1773,7 +1769,9 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 				break;
 
 			release_sock(sk);
+			prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
 			timeout = schedule_timeout(timeout);
+			finish_wait(sk_sleep(sk), &wait);
 			lock_sock(sk);
 
 			if (signal_pending(current)) {
@@ -1783,9 +1781,6 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 				err = -EAGAIN;
 				break;
 			}
-
-			prepare_to_wait(sk_sleep(sk), &wait,
-					TASK_INTERRUPTIBLE);
 		}
 	}
 
@@ -1816,8 +1811,6 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 		err = copied;
 	}
 
-out_wait:
-	finish_wait(sk_sleep(sk), &wait);
 out:
 	release_sock(sk);
 	return err;
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCHv2] vsock: Fix blocking ops call in prepare_to_wait
  2016-02-04 18:50 [PATCHv2] vsock: Fix blocking ops call in prepare_to_wait Laura Abbott
@ 2016-02-13 10:59 ` David Miller
  2016-03-11 12:39   ` Claudio Imbrenda
  0 siblings, 1 reply; 6+ messages in thread
From: David Miller @ 2016-02-13 10:59 UTC (permalink / raw)
  To: labbott; +Cc: asarwade, thellstrom, jhansen, netdev, linux-kernel

From: Laura Abbott <labbott@fedoraproject.org>
Date: Thu,  4 Feb 2016 10:50:45 -0800

> We receoved a bug report from someone using vmware:
 ...
> transport->stream_enqueue may call copy_to_user so it should
> not be called inside a prepare_to_wait. Narrow the scope of
> the prepare_to_wait to avoid the bad call. This also applies
> to vsock_stream_recvmsg as well.
> 
> Reported-by: Vinson Lee <vlee@freedesktop.org>
> Tested-by: Vinson Lee <vlee@freedesktop.org>
> Signed-off-by: Laura Abbott <labbott@fedoraproject.org>

Applied.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCHv2] vsock: Fix blocking ops call in prepare_to_wait
  2016-02-13 10:59 ` David Miller
@ 2016-03-11 12:39   ` Claudio Imbrenda
  2016-03-14 19:24     ` David Miller
  0 siblings, 1 reply; 6+ messages in thread
From: Claudio Imbrenda @ 2016-03-11 12:39 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev, labbott, davem

Hello, 

I think I found a problem with the patch submitted by Laura Abbott
( https://lkml.org/lkml/2016/2/4/711 ): we might miss wakeups.
Since the condition is not checked between the prepare_to_wait and the
schedule(), if a wakeup happens after the condition is checked but before
the sleep happens, and we miss it. ( A description of the problem can be
found here: http://www.makelinux.net/ldd3/chp-6-sect-2 ).

My solution (see patch below) is to shrink the area influenced by
prepare_to_wait, but keeping the fragile section around the condition, and
keep the rest of the code in "normal" running state.  This way the sleep is
correct and the other functions don't need to worry.  The only caveat here
is that the function(s) called to verify the conditions are really not
allowed to sleep, so if you need synchronization in the backend of e.g. 
vsock_stream_has_space(), you should use spinlocks and not mutexes.

In case we want to be able to sleep while waiting for conditions, we can
consider this instead: https://lwn.net/Articles/628628/ .


I stumbled on this problem while working on fixing the upcoming virtio
backend for vsock, below is the patch I had prepared, with the original
message.

---
When a thread is prepared for waiting by calling prepare_to_wait, sleeping
is not allowed until either the wait has taken place or finish_wait has
been called.  The existing code in af_vsock imposed unnecessary no-sleep
assumptions to a broad list of backend functions.
This patch shrinks the influence of prepare_to_wait to the area where it
is strictly needed, therefore relaxing the no-sleep restriction there.

Signed-off-by: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
---
 net/vmw_vsock/af_vsock.c | 158 +++++++++++++++++++++++++----------------------
 1 file changed, 85 insertions(+), 73 deletions(-)

diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 9783a38..112fa8b 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -1209,10 +1209,14 @@ static int vsock_stream_connect(struct socket *sock, struct sockaddr *addr,
 
 		if (signal_pending(current)) {
 			err = sock_intr_errno(timeout);
-			goto out_wait_error;
+			sk->sk_state = SS_UNCONNECTED;
+			sock->state = SS_UNCONNECTED;
+			goto out_wait;
 		} else if (timeout == 0) {
 			err = -ETIMEDOUT;
-			goto out_wait_error;
+			sk->sk_state = SS_UNCONNECTED;
+			sock->state = SS_UNCONNECTED;
+			goto out_wait;
 		}
 
 		prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
@@ -1220,20 +1224,17 @@ static int vsock_stream_connect(struct socket *sock, struct sockaddr *addr,
 
 	if (sk->sk_err) {
 		err = -sk->sk_err;
-		goto out_wait_error;
-	} else
+		sk->sk_state = SS_UNCONNECTED;
+		sock->state = SS_UNCONNECTED;
+	} else {
 		err = 0;
+	}
 
 out_wait:
 	finish_wait(sk_sleep(sk), &wait);
 out:
 	release_sock(sk);
 	return err;
-
-out_wait_error:
-	sk->sk_state = SS_UNCONNECTED;
-	sock->state = SS_UNCONNECTED;
-	goto out_wait;
 }
 
 static int vsock_accept(struct socket *sock, struct socket *newsock, int flags)
@@ -1270,18 +1271,20 @@ static int vsock_accept(struct socket *sock, struct socket *newsock, int flags)
 	       listener->sk_err == 0) {
 		release_sock(listener);
 		timeout = schedule_timeout(timeout);
+		finish_wait(sk_sleep(listener), &wait);
 		lock_sock(listener);
 
 		if (signal_pending(current)) {
 			err = sock_intr_errno(timeout);
-			goto out_wait;
+			goto out;
 		} else if (timeout == 0) {
 			err = -EAGAIN;
-			goto out_wait;
+			goto out;
 		}
 
 		prepare_to_wait(sk_sleep(listener), &wait, TASK_INTERRUPTIBLE);
 	}
+	finish_wait(sk_sleep(listener), &wait);
 
 	if (listener->sk_err)
 		err = -listener->sk_err;
@@ -1301,19 +1304,15 @@ static int vsock_accept(struct socket *sock, struct socket *newsock, int flags)
 		 */
 		if (err) {
 			vconnected->rejected = true;
-			release_sock(connected);
-			sock_put(connected);
-			goto out_wait;
+		} else {
+			newsock->state = SS_CONNECTED;
+			sock_graft(connected, newsock);
 		}
 
-		newsock->state = SS_CONNECTED;
-		sock_graft(connected, newsock);
 		release_sock(connected);
 		sock_put(connected);
 	}
 
-out_wait:
-	finish_wait(sk_sleep(listener), &wait);
 out:
 	release_sock(listener);
 	return err;
@@ -1557,11 +1556,11 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
 	if (err < 0)
 		goto out;
 
-	prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
 
 	while (total_written < len) {
 		ssize_t written;
 
+		prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
 		while (vsock_stream_has_space(vsk) == 0 &&
 		       sk->sk_err == 0 &&
 		       !(sk->sk_shutdown & SEND_SHUTDOWN) &&
@@ -1570,27 +1569,33 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
 			/* Don't wait for non-blocking sockets. */
 			if (timeout == 0) {
 				err = -EAGAIN;
-				goto out_wait;
+				finish_wait(sk_sleep(sk), &wait);
+				goto out_err;
 			}
 
 			err = transport->notify_send_pre_block(vsk, &send_data);
-			if (err < 0)
-				goto out_wait;
+			if (err < 0) {
+				finish_wait(sk_sleep(sk), &wait);
+				goto out_err;
+			}
 
 			release_sock(sk);
 			timeout = schedule_timeout(timeout);
 			lock_sock(sk);
 			if (signal_pending(current)) {
 				err = sock_intr_errno(timeout);
-				goto out_wait;
+				finish_wait(sk_sleep(sk), &wait);
+				goto out_err;
 			} else if (timeout == 0) {
 				err = -EAGAIN;
-				goto out_wait;
+				finish_wait(sk_sleep(sk), &wait);
+				goto out_err;
 			}
 
 			prepare_to_wait(sk_sleep(sk), &wait,
 					TASK_INTERRUPTIBLE);
 		}
+		finish_wait(sk_sleep(sk), &wait);
 
 		/* These checks occur both as part of and after the loop
 		 * conditional since we need to check before and after
@@ -1598,16 +1603,16 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
 		 */
 		if (sk->sk_err) {
 			err = -sk->sk_err;
-			goto out_wait;
+			goto out_err;
 		} else if ((sk->sk_shutdown & SEND_SHUTDOWN) ||
 			   (vsk->peer_shutdown & RCV_SHUTDOWN)) {
 			err = -EPIPE;
-			goto out_wait;
+			goto out_err;
 		}
 
 		err = transport->notify_send_pre_enqueue(vsk, &send_data);
 		if (err < 0)
-			goto out_wait;
+			goto out_err;
 
 		/* Note that enqueue will only write as many bytes as are free
 		 * in the produce queue, so we don't need to ensure len is
@@ -1620,7 +1625,7 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
 				len - total_written);
 		if (written < 0) {
 			err = -ENOMEM;
-			goto out_wait;
+			goto out_err;
 		}
 
 		total_written += written;
@@ -1628,14 +1633,13 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
 		err = transport->notify_send_post_enqueue(
 				vsk, written, &send_data);
 		if (err < 0)
-			goto out_wait;
+			goto out_err;
 
 	}
 
-out_wait:
+out_err:
 	if (total_written > 0)
 		err = total_written;
-	finish_wait(sk_sleep(sk), &wait);
 out:
 	release_sock(sk);
 	return err;
@@ -1716,21 +1720,61 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 	if (err < 0)
 		goto out;
 
-	prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
 
 	while (1) {
-		s64 ready = vsock_stream_has_data(vsk);
+		s64 ready;
 
-		if (ready < 0) {
-			/* Invalid queue pair content. XXX This should be
-			 * changed to a connection reset in a later change.
-			 */
+		prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
+		ready = vsock_stream_has_data(vsk);
 
-			err = -ENOMEM;
-			goto out_wait;
-		} else if (ready > 0) {
+		if (ready == 0) {
+			if (sk->sk_err != 0 ||
+			    (sk->sk_shutdown & RCV_SHUTDOWN) ||
+			    (vsk->peer_shutdown & SEND_SHUTDOWN)) {
+				finish_wait(sk_sleep(sk), &wait);
+				break;
+			}
+			/* Don't wait for non-blocking sockets. */
+			if (timeout == 0) {
+				err = -EAGAIN;
+				finish_wait(sk_sleep(sk), &wait);
+				break;
+			}
+
+			err = transport->notify_recv_pre_block(
+					vsk, target, &recv_data);
+			if (err < 0) {
+				finish_wait(sk_sleep(sk), &wait);
+				break;
+			}
+			release_sock(sk);
+			timeout = schedule_timeout(timeout);
+			lock_sock(sk);
+
+			if (signal_pending(current)) {
+				err = sock_intr_errno(timeout);
+				finish_wait(sk_sleep(sk), &wait);
+				break;
+			} else if (timeout == 0) {
+				err = -EAGAIN;
+				finish_wait(sk_sleep(sk), &wait);
+				break;
+			}
+		} else {
 			ssize_t read;
 
+			finish_wait(sk_sleep(sk), &wait);
+
+			if (ready < 0) {
+				/* Invalid queue pair content. XXX This should
+				* be changed to a connection reset in a later
+				* change.
+				*/
+
+				err = -ENOMEM;
+				goto out;
+			}
+
 			err = transport->notify_recv_pre_dequeue(
 					vsk, target, &recv_data);
 			if (err < 0)
@@ -1750,42 +1794,12 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 					vsk, target, read,
 					!(flags & MSG_PEEK), &recv_data);
 			if (err < 0)
-				goto out_wait;
+				goto out;
 
 			if (read >= target || flags & MSG_PEEK)
 				break;
 
 			target -= read;
-		} else {
-			if (sk->sk_err != 0 || (sk->sk_shutdown & RCV_SHUTDOWN)
-			    || (vsk->peer_shutdown & SEND_SHUTDOWN)) {
-				break;
-			}
-			/* Don't wait for non-blocking sockets. */
-			if (timeout == 0) {
-				err = -EAGAIN;
-				break;
-			}
-
-			err = transport->notify_recv_pre_block(
-					vsk, target, &recv_data);
-			if (err < 0)
-				break;
-
-			release_sock(sk);
-			timeout = schedule_timeout(timeout);
-			lock_sock(sk);
-
-			if (signal_pending(current)) {
-				err = sock_intr_errno(timeout);
-				break;
-			} else if (timeout == 0) {
-				err = -EAGAIN;
-				break;
-			}
-
-			prepare_to_wait(sk_sleep(sk), &wait,
-					TASK_INTERRUPTIBLE);
 		}
 	}
 
@@ -1816,8 +1830,6 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 		err = copied;
 	}
 
-out_wait:
-	finish_wait(sk_sleep(sk), &wait);
 out:
 	release_sock(sk);
 	return err;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCHv2] vsock: Fix blocking ops call in prepare_to_wait
  2016-03-11 12:39   ` Claudio Imbrenda
@ 2016-03-14 19:24     ` David Miller
  2016-03-14 20:07       ` Laura Abbott
  0 siblings, 1 reply; 6+ messages in thread
From: David Miller @ 2016-03-14 19:24 UTC (permalink / raw)
  To: imbrenda; +Cc: linux-kernel, netdev, labbott

From: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
Date: Fri, 11 Mar 2016 13:39:23 +0100

> I think I found a problem with the patch submitted by Laura Abbott
> ( https://lkml.org/lkml/2016/2/4/711 ): we might miss wakeups.
> Since the condition is not checked between the prepare_to_wait and the
> schedule(), if a wakeup happens after the condition is checked but before
> the sleep happens, and we miss it. ( A description of the problem can be
> found here: http://www.makelinux.net/ldd3/chp-6-sect-2 ).
> 
> My solution (see patch below) is to shrink the area influenced by
> prepare_to_wait, but keeping the fragile section around the condition, and
> keep the rest of the code in "normal" running state.  This way the sleep is
> correct and the other functions don't need to worry.  The only caveat here
> is that the function(s) called to verify the conditions are really not
> allowed to sleep, so if you need synchronization in the backend of e.g. 
> vsock_stream_has_space(), you should use spinlocks and not mutexes.
> 
> In case we want to be able to sleep while waiting for conditions, we can
> consider this instead: https://lwn.net/Articles/628628/ .
> 
> 
> I stumbled on this problem while working on fixing the upcoming virtio
> backend for vsock, below is the patch I had prepared, with the original
> message.

Can someone please look at this?  Who maintains this code anyways?

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCHv2] vsock: Fix blocking ops call in prepare_to_wait
  2016-03-14 19:24     ` David Miller
@ 2016-03-14 20:07       ` Laura Abbott
  2016-03-16 23:19         ` David Miller
  0 siblings, 1 reply; 6+ messages in thread
From: Laura Abbott @ 2016-03-14 20:07 UTC (permalink / raw)
  To: David Miller, imbrenda; +Cc: linux-kernel, netdev, labbott

On 03/14/2016 12:24 PM, David Miller wrote:
> From: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
> Date: Fri, 11 Mar 2016 13:39:23 +0100
>
>> I think I found a problem with the patch submitted by Laura Abbott
>> ( https://lkml.org/lkml/2016/2/4/711 ): we might miss wakeups.
>> Since the condition is not checked between the prepare_to_wait and the
>> schedule(), if a wakeup happens after the condition is checked but before
>> the sleep happens, and we miss it. ( A description of the problem can be
>> found here: http://www.makelinux.net/ldd3/chp-6-sect-2 ).
>>
>> My solution (see patch below) is to shrink the area influenced by
>> prepare_to_wait, but keeping the fragile section around the condition, and
>> keep the rest of the code in "normal" running state.  This way the sleep is
>> correct and the other functions don't need to worry.  The only caveat here
>> is that the function(s) called to verify the conditions are really not
>> allowed to sleep, so if you need synchronization in the backend of e.g.
>> vsock_stream_has_space(), you should use spinlocks and not mutexes.
>>
>> In case we want to be able to sleep while waiting for conditions, we can
>> consider this instead: https://lwn.net/Articles/628628/ .
>>
>>
>> I stumbled on this problem while working on fixing the upcoming virtio
>> backend for vsock, below is the patch I had prepared, with the original
>> message.
>
> Can someone please look at this?  Who maintains this code anyways?
>

Nobody was listed in MAINTAINERS. I tried cc-ing some of the e-mail addresses
of the original authors (vmware?) when sending the original patch and they
all bounced.

Thanks,
Laura

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCHv2] vsock: Fix blocking ops call in prepare_to_wait
  2016-03-14 20:07       ` Laura Abbott
@ 2016-03-16 23:19         ` David Miller
  0 siblings, 0 replies; 6+ messages in thread
From: David Miller @ 2016-03-16 23:19 UTC (permalink / raw)
  To: labbott; +Cc: imbrenda, linux-kernel, netdev, labbott

From: Laura Abbott <labbott@redhat.com>
Date: Mon, 14 Mar 2016 13:07:06 -0700

> On 03/14/2016 12:24 PM, David Miller wrote:
>> From: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
>> Date: Fri, 11 Mar 2016 13:39:23 +0100
>>
>>> I think I found a problem with the patch submitted by Laura Abbott
>>> ( https://lkml.org/lkml/2016/2/4/711 ): we might miss wakeups.
>>> Since the condition is not checked between the prepare_to_wait and the
>>> schedule(), if a wakeup happens after the condition is checked but
>>> before
>>> the sleep happens, and we miss it. ( A description of the problem can
>>> be
>>> found here: http://www.makelinux.net/ldd3/chp-6-sect-2 ).
>>>
>>> My solution (see patch below) is to shrink the area influenced by
>>> prepare_to_wait, but keeping the fragile section around the condition,
>>> and
>>> keep the rest of the code in "normal" running state.  This way the
>>> sleep is
>>> correct and the other functions don't need to worry.  The only caveat
>>> here
>>> is that the function(s) called to verify the conditions are really not
>>> allowed to sleep, so if you need synchronization in the backend of
>>> e.g.
>>> vsock_stream_has_space(), you should use spinlocks and not mutexes.
>>>
>>> In case we want to be able to sleep while waiting for conditions, we
>>> can
>>> consider this instead: https://lwn.net/Articles/628628/ .
>>>
>>>
>>> I stumbled on this problem while working on fixing the upcoming virtio
>>> backend for vsock, below is the patch I had prepared, with the
>>> original
>>> message.
>>
>> Can someone please look at this?  Who maintains this code anyways?
>>
> 
> Nobody was listed in MAINTAINERS. I tried cc-ing some of the e-mail
> addresses
> of the original authors (vmware?) when sending the original patch and
> they
> all bounced.

Ok, can you please submit this anew?  Your commit message format was
incorrect, you put the commit message content you wanted in the change
after the --- separater instead of beforehand.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2016-03-16 23:19 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-04 18:50 [PATCHv2] vsock: Fix blocking ops call in prepare_to_wait Laura Abbott
2016-02-13 10:59 ` David Miller
2016-03-11 12:39   ` Claudio Imbrenda
2016-03-14 19:24     ` David Miller
2016-03-14 20:07       ` Laura Abbott
2016-03-16 23:19         ` David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.