diff mbox

tcp: add memory barriers to write space paths

Message ID 20150420200507.21414203F@prod-mail-relay06.akamai.com
State Accepted, archived
Delegated to: David Miller
Headers show

Commit Message

Jason Baron April 20, 2015, 8:05 p.m. UTC
Ensure that we either see that the buffer has write space
in tcp_poll() or that we perform a wakeup from the input
side. Did not run into any actual problem here, but thought
that we should make things explicit.

Signed-off-by: Jason Baron <jbaron@akamai.com>
---
 net/ipv4/tcp.c       | 4 +++-
 net/ipv4/tcp_input.c | 2 ++
 2 files changed, 5 insertions(+), 1 deletion(-)

Comments

David Miller April 21, 2015, 7:58 p.m. UTC | #1
From: Jason Baron <jbaron@akamai.com>
Date: Mon, 20 Apr 2015 20:05:07 +0000 (GMT)

> Ensure that we either see that the buffer has write space
> in tcp_poll() or that we perform a wakeup from the input
> side. Did not run into any actual problem here, but thought
> that we should make things explicit.
> 
> Signed-off-by: Jason Baron <jbaron@akamai.com>

This looks fine, applied, thanks.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 094a682..726341e 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -520,8 +520,10 @@  unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait)
 
 				/* Race breaker. If space is freed after
 				 * wspace test but before the flags are set,
-				 * IO signal will be lost.
+				 * IO signal will be lost. Memory barrier
+				 * pairs with the input side.
 				 */
+				smp_mb__after_atomic();
 				if (sk_stream_is_writeable(sk))
 					mask |= POLLOUT | POLLWRNORM;
 			}
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 031cf72..63b3d4e9 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4847,6 +4847,8 @@  static void tcp_check_space(struct sock *sk)
 {
 	if (sock_flag(sk, SOCK_QUEUE_SHRUNK)) {
 		sock_reset_flag(sk, SOCK_QUEUE_SHRUNK);
+		/* pairs with tcp_poll() */
+		smp_mb__after_atomic();
 		if (sk->sk_socket &&
 		    test_bit(SOCK_NOSPACE, &sk->sk_socket->flags))
 			tcp_new_space(sk);