[TCP]: Do not purge sk_forward_alloc entirely in tcp_delack_timer().
authorDavid S. Miller <davem@davemloft.net>
Fri, 11 Jan 2008 05:56:38 +0000 (21:56 -0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 28 Jan 2008 23:01:42 +0000 (15:01 -0800)
Otherwise we beat heavily on the global tcp_memory atomics
when all of the sockets in the system are slowly sending
perioding packet clumps.

Noticed and suggested by Eric Dumazet.

Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/sock.h
net/ipv4/tcp_timer.c

index 786fae858e77027e5b5725ff41678893c796c95f..902324488d0f7d2fb9a485258f59efa827344b0f 100644 (file)
@@ -759,6 +759,14 @@ static inline void sk_mem_reclaim(struct sock *sk)
                __sk_mem_reclaim(sk);
 }
 
+static inline void sk_mem_reclaim_partial(struct sock *sk)
+{
+       if (!sk_has_account(sk))
+               return;
+       if (sk->sk_forward_alloc > SK_MEM_QUANTUM)
+               __sk_mem_reclaim(sk);
+}
+
 static inline void sk_mem_charge(struct sock *sk, int size)
 {
        if (!sk_has_account(sk))
index 17931be6d584e0022117e98075bf149e8e4dad2c..803d758a2b124f0301f9dae7dbbd750722acf5e9 100644 (file)
@@ -186,7 +186,7 @@ static void tcp_delack_timer(unsigned long data)
                goto out_unlock;
        }
 
-       sk_mem_reclaim(sk);
+       sk_mem_reclaim_partial(sk);
 
        if (sk->sk_state == TCP_CLOSE || !(icsk->icsk_ack.pending & ICSK_ACK_TIMER))
                goto out;