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/ipv4 | |
| 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/ipv4')
| -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); |
