]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
mlx4_en: fix skb truesize underestimation
authorJoe Jin <joe.jin@oracle.com>
Thu, 15 Dec 2011 01:36:34 +0000 (09:36 +0800)
committerJoe Jin <joe.jin@oracle.com>
Thu, 15 Dec 2011 01:36:34 +0000 (09:36 +0800)
commit 90278c9ffb8a92672d60a618a58a99e2370a98ac
Author: Eric Dumazet <eric.dumazet@gmail.com>
Date:   Wed Oct 19 18:49:52 2011 +0000

    mlx4_en: fix skb truesize underestimation

    skb->truesize must account for allocated memory, not the used part of
    it. Doing this work is important to avoid unexpected OOM situations.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
CC: Yevgeny Petrilin <yevgenyp@mellanox.co.il>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Joe Jin <joe.jin@oracle.com>
drivers/net/mlx4/en_rx.c

index 1bc0f99c9bc7e48dd6ec1fac6d58f51c50460569..263c1544ce502c3d0f41c527a4b6a7c778e0cb87 100644 (file)
@@ -404,10 +404,11 @@ void mlx4_en_deactivate_rx_ring(struct mlx4_en_priv *priv,
 static int mlx4_en_complete_rx_desc(struct mlx4_en_priv *priv,
                                    struct mlx4_en_rx_desc *rx_desc,
                                    struct skb_frag_struct *skb_frags,
-                                   struct skb_frag_struct *skb_frags_rx,
+                                   struct sk_buff *skb,
                                    struct mlx4_en_rx_alloc *page_alloc,
                                    int length)
 {
+       struct skb_frag_struct *skb_frags_rx = skb_shinfo(skb)->frags;
        struct mlx4_en_dev *mdev = priv->mdev;
        struct mlx4_en_frag_info *frag_info;
        int nr;
@@ -423,6 +424,7 @@ static int mlx4_en_complete_rx_desc(struct mlx4_en_priv *priv,
                skb_frags_rx[nr].page = skb_frags[nr].page;
                skb_frags_rx[nr].size = skb_frags[nr].size;
                skb_frags_rx[nr].page_offset = skb_frags[nr].page_offset;
+               skb->truesize += frag_info->frag_stride;
                dma = be64_to_cpu(rx_desc->data[nr].addr);
 
                /* Allocate a replacement page */
@@ -470,7 +472,6 @@ static struct sk_buff *mlx4_en_rx_skb(struct mlx4_en_priv *priv,
        skb->dev = priv->dev;
        skb_reserve(skb, NET_IP_ALIGN);
        skb->len = length;
-       skb->truesize = length + sizeof(struct sk_buff);
 
        /* Get pointer to first fragment so we could copy the headers into the
         * (linear part of the) skb */
@@ -490,8 +491,7 @@ static struct sk_buff *mlx4_en_rx_skb(struct mlx4_en_priv *priv,
 
                /* Move relevant fragments to skb */
                used_frags = mlx4_en_complete_rx_desc(priv, rx_desc, skb_frags,
-                                                     skb_shinfo(skb)->frags,
-                                                     page_alloc, length);
+                                                     skb, page_alloc, length);
                if (unlikely(!used_frags)) {
                        kfree_skb(skb);
                        return NULL;
@@ -600,7 +600,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
 
                                        nr = mlx4_en_complete_rx_desc(
                                                priv, rx_desc,
-                                               skb_frags, skb_shinfo(gro_skb)->frags,
+                                               skb_frags, gro_skb,
                                                ring->page_alloc, length);
                                        if (!nr)
                                                goto next;
@@ -608,7 +608,6 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
                                        skb_shinfo(gro_skb)->nr_frags = nr;
                                        gro_skb->len = length;
                                        gro_skb->data_len = length;
-                                       gro_skb->truesize += length;
                                        gro_skb->ip_summed = CHECKSUM_UNNECESSARY;
 
                                        if (cqe->vlan_my_qpn &