diff options
author | jbaron@akamai.com <jbaron@akamai.com> | 2015-04-20 16:05:07 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-04-21 15:57:34 -0400 |
commit | 3c7151275c0c9a80c3375f9874b1c7129a105eea (patch) | |
tree | d1c703725e11d908f2d027dd62c22f83bc1e0c19 /net | |
parent | 71cd26e76a9514715df7880db0a8f7c37c17149a (diff) |
tcp: add memory barriers to write space paths
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>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/tcp.c | 4 | ||||
-rw-r--r-- | net/ipv4/tcp_input.c | 2 |
2 files changed, 5 insertions, 1 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 59c8a027721b..8c5cd9efebbc 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) | |||
520 | 520 | ||
521 | /* Race breaker. If space is freed after | 521 | /* Race breaker. If space is freed after |
522 | * wspace test but before the flags are set, | 522 | * wspace test but before the flags are set, |
523 | * IO signal will be lost. | 523 | * IO signal will be lost. Memory barrier |
524 | * pairs with the input side. | ||
524 | */ | 525 | */ |
526 | smp_mb__after_atomic(); | ||
525 | if (sk_stream_is_writeable(sk)) | 527 | if (sk_stream_is_writeable(sk)) |
526 | mask |= POLLOUT | POLLWRNORM; | 528 | mask |= POLLOUT | POLLWRNORM; |
527 | } | 529 | } |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index a7ef679dd3ea..3a4d9b34bed4 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -4845,6 +4845,8 @@ static void tcp_check_space(struct sock *sk) | |||
4845 | { | 4845 | { |
4846 | if (sock_flag(sk, SOCK_QUEUE_SHRUNK)) { | 4846 | if (sock_flag(sk, SOCK_QUEUE_SHRUNK)) { |
4847 | sock_reset_flag(sk, SOCK_QUEUE_SHRUNK); | 4847 | sock_reset_flag(sk, SOCK_QUEUE_SHRUNK); |
4848 | /* pairs with tcp_poll() */ | ||
4849 | smp_mb__after_atomic(); | ||
4848 | if (sk->sk_socket && | 4850 | if (sk->sk_socket && |
4849 | test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) | 4851 | test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) |
4850 | tcp_new_space(sk); | 4852 | tcp_new_space(sk); |