From 54789a03adf9c924d0cf7b890323c9c1ca7ab042 Mon Sep 17 00:00:00 2001 From: Daniel Hellstrom <daniel@gaisler.com> Date: Wed, 1 Dec 2010 10:26:09 +0100 Subject: [PATCH] GRETH: fixed skb buffer memory leak on frame errors A new SKB buffer should not be allocated when the old SKB is reused. Signed-off-by: Daniel Hellstrom <daniel@gaisler.com> --- drivers/net/greth.c | 17 +++++++++++------ 1 files changed, 11 insertions(+), 6 deletions(-) --- a/drivers/net/greth.c +++ b/drivers/net/greth.c @@ -879,10 +879,8 @@ static int greth_rx_gbit(struct net_devi } } - /* Allocate new skb to replace current */ - newskb = netdev_alloc_skb(dev, MAX_FRAME_SIZE + NET_IP_ALIGN); - - if (!bad && newskb) { + /* Allocate new skb to replace current, not needed if the current skb can be reused */ + if (!bad && (newskb=netdev_alloc_skb(dev, MAX_FRAME_SIZE + NET_IP_ALIGN))) { skb_reserve(newskb, NET_IP_ALIGN); dma_addr = dma_map_single(greth->dev, @@ -919,12 +917,19 @@ static int greth_rx_gbit(struct net_devi if (net_ratelimit()) dev_warn(greth->dev, "Could not create DMA mapping, dropping packet\n"); dev_kfree_skb(newskb); - dev->stats.rx_dropped++; + dev->stats.rx_dropped++; /* reusing current skb, so it is a drop */ } + } else if ( bad ) { + /* Bad Frame transfer, the skb is reused */ + dev->stats.rx_dropped++; } else { + /* Failed Allocating a new skb. This is rather stupid but the current "filled" + * skb is reused, as if transfer failure. One could argue that RX descriptor table + * handling should be divided into cleaning and filling as the TX part of the driver + */ if (net_ratelimit()) dev_warn(greth->dev, "Could not allocate SKB, dropping packet\n"); - dev->stats.rx_dropped++; + dev->stats.rx_dropped++; /* reusing current skb, so it is a drop */ } status = GRETH_BD_EN | GRETH_BD_IE;