Commit efcdbf24 authored by Arun Sharma's avatar Arun Sharma Committed by David S. Miller

net: Disambiguate kernel message

Some of our machines were reporting:

TCP: too many of orphaned sockets

even when the number of orphaned sockets was well below the
limit.

We print a different message depending on whether we're out
of TCP memory or there are too many orphaned sockets.

Also move the check out of line and cleanup the messages
that were printed.
Signed-off-by: default avatarArun Sharma <asharma@fb.com>
Suggested-by: default avatarMohan Srinivasan <mohan@fb.com>
Cc: netdev@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: David Miller <davem@davemloft.net>
Cc: Glauber Costa <glommer@parallels.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Joe Perches <joe@perches.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 48c38839
...@@ -273,6 +273,14 @@ static inline int between(__u32 seq1, __u32 seq2, __u32 seq3) ...@@ -273,6 +273,14 @@ static inline int between(__u32 seq1, __u32 seq2, __u32 seq3)
return seq3 - seq2 >= seq1 - seq2; return seq3 - seq2 >= seq1 - seq2;
} }
static inline bool tcp_out_of_memory(struct sock *sk)
{
if (sk->sk_wmem_queued > SOCK_MIN_SNDBUF &&
sk_memory_allocated(sk) > sk_prot_mem_limits(sk, 2))
return true;
return false;
}
static inline bool tcp_too_many_orphans(struct sock *sk, int shift) static inline bool tcp_too_many_orphans(struct sock *sk, int shift)
{ {
struct percpu_counter *ocp = sk->sk_prot->orphan_count; 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,13 +291,11 @@ static inline bool tcp_too_many_orphans(struct sock *sk, int shift)
if (orphans << shift > sysctl_tcp_max_orphans) if (orphans << shift > sysctl_tcp_max_orphans)
return true; return true;
} }
if (sk->sk_wmem_queued > SOCK_MIN_SNDBUF &&
sk_memory_allocated(sk) > sk_prot_mem_limits(sk, 2))
return true;
return false; return false;
} }
extern bool tcp_check_oom(struct sock *sk, int shift);
/* syncookies: remember time of last synqueue overflow */ /* syncookies: remember time of last synqueue overflow */
static inline void tcp_synq_overflow(struct sock *sk) static inline void tcp_synq_overflow(struct sock *sk)
{ {
......
...@@ -1876,6 +1876,20 @@ void tcp_shutdown(struct sock *sk, int how) ...@@ -1876,6 +1876,20 @@ void tcp_shutdown(struct sock *sk, int how)
} }
EXPORT_SYMBOL(tcp_shutdown); EXPORT_SYMBOL(tcp_shutdown);
bool tcp_check_oom(struct sock *sk, int shift)
{
bool too_many_orphans, out_of_socket_memory;
too_many_orphans = tcp_too_many_orphans(sk, shift);
out_of_socket_memory = tcp_out_of_memory(sk);
if (too_many_orphans && net_ratelimit())
pr_info("TCP: too many orphaned sockets\n");
if (out_of_socket_memory && net_ratelimit())
pr_info("TCP: out of memory -- consider tuning tcp_mem\n");
return too_many_orphans || out_of_socket_memory;
}
void tcp_close(struct sock *sk, long timeout) void tcp_close(struct sock *sk, long timeout)
{ {
struct sk_buff *skb; struct sk_buff *skb;
...@@ -2015,10 +2029,7 @@ void tcp_close(struct sock *sk, long timeout) ...@@ -2015,10 +2029,7 @@ void tcp_close(struct sock *sk, long timeout)
} }
if (sk->sk_state != TCP_CLOSE) { if (sk->sk_state != TCP_CLOSE) {
sk_mem_reclaim(sk); sk_mem_reclaim(sk);
if (tcp_too_many_orphans(sk, 0)) { if (tcp_check_oom(sk, 0)) {
if (net_ratelimit())
printk(KERN_INFO "TCP: too many of orphaned "
"sockets\n");
tcp_set_state(sk, TCP_CLOSE); tcp_set_state(sk, TCP_CLOSE);
tcp_send_active_reset(sk, GFP_ATOMIC); tcp_send_active_reset(sk, GFP_ATOMIC);
NET_INC_STATS_BH(sock_net(sk), NET_INC_STATS_BH(sock_net(sk),
......
...@@ -77,10 +77,7 @@ static int tcp_out_of_resources(struct sock *sk, int do_reset) ...@@ -77,10 +77,7 @@ static int tcp_out_of_resources(struct sock *sk, int do_reset)
if (sk->sk_err_soft) if (sk->sk_err_soft)
shift++; shift++;
if (tcp_too_many_orphans(sk, shift)) { if (tcp_check_oom(sk, shift)) {
if (net_ratelimit())
printk(KERN_INFO "Out of socket memory\n");
/* Catch exceptional cases, when connection requires reset. /* Catch exceptional cases, when connection requires reset.
* 1. Last segment was sent recently. */ * 1. Last segment was sent recently. */
if ((s32)(tcp_time_stamp - tp->lsndtime) <= TCP_TIMEWAIT_LEN || if ((s32)(tcp_time_stamp - tp->lsndtime) <= TCP_TIMEWAIT_LEN ||
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment