lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Fri, 14 Oct 2011 18:11:54 +0200 From: Eric Dumazet <eric.dumazet@...il.com> To: Rick Jones <rick.jones2@...com> Cc: David Miller <davem@...emloft.net>, netdev@...r.kernel.org Subject: Re: [PATCH net-next] tcp: reduce memory needs of out of order queue Le vendredi 14 octobre 2011 à 18:00 +0200, Eric Dumazet a écrit : > Now we also could do the copybreak for frames queued into regular > receive_queue, if current wmem_alloc is above 25% of rcvbuf space... I mean rmem_alloc of course... diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index c1653fe..0fe0828 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -4426,6 +4426,25 @@ static inline int tcp_try_rmem_schedule(struct sock *sk, unsigned int size) return 0; } +/* + * Caller want to reduce memory needs before queueing skb + * The (expensive) copy should not be be done in fast path. + */ +static struct sk_buff *skb_reduce_truesize(struct sk_buff *skb) +{ + if (skb->truesize > 2 * SKB_TRUESIZE(skb->len)) { + struct sk_buff *nskb; + + nskb = skb_copy_expand(skb, skb_headroom(skb), 0, + GFP_ATOMIC | __GFP_NOWARN); + if (nskb) { + __kfree_skb(skb); + skb = nskb; + } + } + return skb; +} + static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) { struct tcphdr *th = tcp_hdr(skb); @@ -4475,6 +4494,10 @@ queue_and_out: tcp_try_rmem_schedule(sk, skb->truesize)) goto drop; + if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf >> 2) { + skb = skb_reduce_truesize(skb); + th = tcp_hdr(skb); + } skb_set_owner_r(skb, sk); __skb_queue_tail(&sk->sk_receive_queue, skb); } @@ -4553,6 +4576,11 @@ drop: SOCK_DEBUG(sk, "out of order segment: rcv_next %X seq %X - %X\n", tp->rcv_nxt, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq); + /* Since this skb might stay on ofo a long time, try to reduce + * its truesize (if its too big) to avoid future pruning. + * Many drivers allocate large buffers even to hold tiny frames. + */ + skb = skb_reduce_truesize(skb); skb_set_owner_r(skb, sk); if (!skb_peek(&tp->out_of_order_queue)) { -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists