diff options
-rw-r--r-- | include/net/tcp.h | 14 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 19 | ||||
-rw-r--r-- | net/ipv4/tcp_timer.c | 5 |
3 files changed, 26 insertions, 12 deletions
diff --git a/include/net/tcp.h b/include/net/tcp.h index d49db0113a06..42c29bfbcee3 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h | |||
@@ -273,6 +273,14 @@ static inline int between(__u32 seq1, __u32 seq2, __u32 seq3) | |||
273 | return seq3 - seq2 >= seq1 - seq2; | 273 | return seq3 - seq2 >= seq1 - seq2; |
274 | } | 274 | } |
275 | 275 | ||
276 | static inline bool tcp_out_of_memory(struct sock *sk) | ||
277 | { | ||
278 | if (sk->sk_wmem_queued > SOCK_MIN_SNDBUF && | ||
279 | sk_memory_allocated(sk) > sk_prot_mem_limits(sk, 2)) | ||
280 | return true; | ||
281 | return false; | ||
282 | } | ||
283 | |||
276 | static inline bool tcp_too_many_orphans(struct sock *sk, int shift) | 284 | static inline bool tcp_too_many_orphans(struct sock *sk, int shift) |
277 | { | 285 | { |
278 | struct percpu_counter *ocp = sk->sk_prot->orphan_count; | 286 | struct percpu_counter *ocp = sk->sk_prot->orphan_count; |
@@ -283,13 +291,11 @@ static inline bool tcp_too_many_orphans(struct sock *sk, int shift) | |||
283 | if (orphans << shift > sysctl_tcp_max_orphans) | 291 | if (orphans << shift > sysctl_tcp_max_orphans) |
284 | return true; | 292 | return true; |
285 | } | 293 | } |
286 | |||
287 | if (sk->sk_wmem_queued > SOCK_MIN_SNDBUF && | ||
288 | sk_memory_allocated(sk) > sk_prot_mem_limits(sk, 2)) | ||
289 | return true; | ||
290 | return false; | 294 | return false; |
291 | } | 295 | } |
292 | 296 | ||
297 | extern bool tcp_check_oom(struct sock *sk, int shift); | ||
298 | |||
293 | /* syncookies: remember time of last synqueue overflow */ | 299 | /* syncookies: remember time of last synqueue overflow */ |
294 | static inline void tcp_synq_overflow(struct sock *sk) | 300 | static inline void tcp_synq_overflow(struct sock *sk) |
295 | { | 301 | { |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 06373b4a449a..a34f5cfdd44c 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -1876,6 +1876,20 @@ void tcp_shutdown(struct sock *sk, int how) | |||
1876 | } | 1876 | } |
1877 | EXPORT_SYMBOL(tcp_shutdown); | 1877 | EXPORT_SYMBOL(tcp_shutdown); |
1878 | 1878 | ||
1879 | bool tcp_check_oom(struct sock *sk, int shift) | ||
1880 | { | ||
1881 | bool too_many_orphans, out_of_socket_memory; | ||
1882 | |||
1883 | too_many_orphans = tcp_too_many_orphans(sk, shift); | ||
1884 | out_of_socket_memory = tcp_out_of_memory(sk); | ||
1885 | |||
1886 | if (too_many_orphans && net_ratelimit()) | ||
1887 | pr_info("TCP: too many orphaned sockets\n"); | ||
1888 | if (out_of_socket_memory && net_ratelimit()) | ||
1889 | pr_info("TCP: out of memory -- consider tuning tcp_mem\n"); | ||
1890 | return too_many_orphans || out_of_socket_memory; | ||
1891 | } | ||
1892 | |||
1879 | void tcp_close(struct sock *sk, long timeout) | 1893 | void tcp_close(struct sock *sk, long timeout) |
1880 | { | 1894 | { |
1881 | struct sk_buff *skb; | 1895 | struct sk_buff *skb; |
@@ -2015,10 +2029,7 @@ adjudge_to_death: | |||
2015 | } | 2029 | } |
2016 | if (sk->sk_state != TCP_CLOSE) { | 2030 | if (sk->sk_state != TCP_CLOSE) { |
2017 | sk_mem_reclaim(sk); | 2031 | sk_mem_reclaim(sk); |
2018 | if (tcp_too_many_orphans(sk, 0)) { | 2032 | if (tcp_check_oom(sk, 0)) { |
2019 | if (net_ratelimit()) | ||
2020 | printk(KERN_INFO "TCP: too many of orphaned " | ||
2021 | "sockets\n"); | ||
2022 | tcp_set_state(sk, TCP_CLOSE); | 2033 | tcp_set_state(sk, TCP_CLOSE); |
2023 | tcp_send_active_reset(sk, GFP_ATOMIC); | 2034 | tcp_send_active_reset(sk, GFP_ATOMIC); |
2024 | NET_INC_STATS_BH(sock_net(sk), | 2035 | NET_INC_STATS_BH(sock_net(sk), |
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index a516d1e399df..cd2e0723266d 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c | |||
@@ -77,10 +77,7 @@ static int tcp_out_of_resources(struct sock *sk, int do_reset) | |||
77 | if (sk->sk_err_soft) | 77 | if (sk->sk_err_soft) |
78 | shift++; | 78 | shift++; |
79 | 79 | ||
80 | if (tcp_too_many_orphans(sk, shift)) { | 80 | if (tcp_check_oom(sk, shift)) { |
81 | if (net_ratelimit()) | ||
82 | printk(KERN_INFO "Out of socket memory\n"); | ||
83 | |||
84 | /* Catch exceptional cases, when connection requires reset. | 81 | /* Catch exceptional cases, when connection requires reset. |
85 | * 1. Last segment was sent recently. */ | 82 | * 1. Last segment was sent recently. */ |
86 | if ((s32)(tcp_time_stamp - tp->lsndtime) <= TCP_TIMEWAIT_LEN || | 83 | if ((s32)(tcp_time_stamp - tp->lsndtime) <= TCP_TIMEWAIT_LEN || |