net: ftgmac100/ftmac100: dont pull too much data
authorEric Dumazet <edumazet@google.com>
Thu, 12 Jul 2012 04:19:38 +0000 (04:19 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 18 Jul 2012 16:40:53 +0000 (09:40 -0700)
Drivers should pull only ethernet header from page frag
to skb->head.

Pulling 64 bytes is too much for TCP (without options) on IPv4.

However, it makes sense to pull all the frame if it fits the
128 bytes bloc allocated for skb->head, to free one page per
small incoming frame.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Po-Yu Chuang <ratbert@faraday-tech.com>
Acked-by: Yan-Pai Chen <yanpai.chen@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/faraday/ftgmac100.c
drivers/net/ethernet/faraday/ftmac100.c

index 16b07048274ce89764eb8dddbcd9adec913eada5..74d749e29aab7725888ec8a273b5ecdd4522dc06 100644 (file)
@@ -479,9 +479,14 @@ static bool ftgmac100_rx_packet(struct ftgmac100 *priv, int *processed)
                rxdes = ftgmac100_current_rxdes(priv);
        } while (!done);
 
-       if (skb->len <= 64)
+       /* Small frames are copied into linear part of skb to free one page */
+       if (skb->len <= 128) {
                skb->truesize -= PAGE_SIZE;
-       __pskb_pull_tail(skb, min(skb->len, 64U));
+               __pskb_pull_tail(skb, skb->len);
+       } else {
+               /* We pull the minimum amount into linear part */
+               __pskb_pull_tail(skb, ETH_HLEN);
+       }
        skb->protocol = eth_type_trans(skb, netdev);
 
        netdev->stats.rx_packets++;
index 829b1092fd78c3b6c3d442ed581e34c496786a8b..b901a01e3fa5073f4b5c8039d94cf04c7beaa849 100644 (file)
@@ -441,11 +441,14 @@ static bool ftmac100_rx_packet(struct ftmac100 *priv, int *processed)
        skb->len += length;
        skb->data_len += length;
 
-       /* page might be freed in __pskb_pull_tail() */
-       if (length > 64)
+       if (length > 128) {
                skb->truesize += PAGE_SIZE;
-       __pskb_pull_tail(skb, min(length, 64));
-
+               /* We pull the minimum amount into linear part */
+               __pskb_pull_tail(skb, ETH_HLEN);
+       } else {
+               /* Small frames are copied into linear part to free one page */
+               __pskb_pull_tail(skb, length);
+       }
        ftmac100_alloc_rx_page(priv, rxdes, GFP_ATOMIC);
 
        ftmac100_rx_pointer_advance(priv);