提交 d903ec77 编写于 作者: A Andy Spencer 提交者: David S. Miller

gianfar: simplify FCS handling and fix memory leak

Previously, buffer descriptors containing only the frame check sequence
(FCS) were skipped and not added to the skb. However, the page reference
count was still incremented, leading to a memory leak.

Fixing this inside gfar_add_rx_frag() is difficult due to reserved
memory handling and page reuse. Instead, move the FCS handling to
gfar_process_frame() and trim off the FCS before passing the skb up the
networking stack.
Signed-off-by: NAndy Spencer <aspencer@spacex.com>
Signed-off-by: NJim Gruen <jgruen@spacex.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 ca79bec2
...@@ -2934,29 +2934,17 @@ static bool gfar_add_rx_frag(struct gfar_rx_buff *rxb, u32 lstatus, ...@@ -2934,29 +2934,17 @@ static bool gfar_add_rx_frag(struct gfar_rx_buff *rxb, u32 lstatus,
{ {
int size = lstatus & BD_LENGTH_MASK; int size = lstatus & BD_LENGTH_MASK;
struct page *page = rxb->page; struct page *page = rxb->page;
bool last = !!(lstatus & BD_LFLAG(RXBD_LAST));
/* Remove the FCS from the packet length */
if (last)
size -= ETH_FCS_LEN;
if (likely(first)) { if (likely(first)) {
skb_put(skb, size); skb_put(skb, size);
} else { } else {
/* the last fragments' length contains the full frame length */ /* the last fragments' length contains the full frame length */
if (last) if (lstatus & BD_LFLAG(RXBD_LAST))
size -= skb->len; size -= skb->len;
/* Add the last fragment if it contains something other than skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
* the FCS, otherwise drop it and trim off any part of the FCS rxb->page_offset + RXBUF_ALIGNMENT,
* that was already received. size, GFAR_RXB_TRUESIZE);
*/
if (size > 0)
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
rxb->page_offset + RXBUF_ALIGNMENT,
size, GFAR_RXB_TRUESIZE);
else if (size < 0)
pskb_trim(skb, skb->len + size);
} }
/* try reuse page */ /* try reuse page */
...@@ -3069,6 +3057,9 @@ static void gfar_process_frame(struct net_device *ndev, struct sk_buff *skb) ...@@ -3069,6 +3057,9 @@ static void gfar_process_frame(struct net_device *ndev, struct sk_buff *skb)
if (priv->padding) if (priv->padding)
skb_pull(skb, priv->padding); skb_pull(skb, priv->padding);
/* Trim off the FCS */
pskb_trim(skb, skb->len - ETH_FCS_LEN);
if (ndev->features & NETIF_F_RXCSUM) if (ndev->features & NETIF_F_RXCSUM)
gfar_rx_checksum(skb, fcb); gfar_rx_checksum(skb, fcb);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册