Patch "net: arc_emac: fix arc_emac_rx() error paths" has been added to the 4.14-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
net: arc_emac: fix arc_emac_rx() error paths
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
net-arc_emac-fix-arc_emac_rx-error-paths.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Wed Feb 28 16:23:28 CET 2018
From: Alexander Kochetkov <[email protected]>
Date: Fri, 15 Dec 2017 20:20:06 +0300
Subject: net: arc_emac: fix arc_emac_rx() error paths
From: Alexander Kochetkov <[email protected]>
[ Upstream commit e688822d035b494071ecbadcccbd6f3325fb0f59 ]
arc_emac_rx() has some issues found by code review.
In case netdev_alloc_skb_ip_align() or dma_map_single() failure rx fifo entry will not be returned to EMAC.
In case dma_map_single() failure previously allocated skb became lost to driver. At the same time address of newly allocated skb will not be provided to EMAC.
--- drivers/net/ethernet/arc/emac_main.c | 53 ++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 22 deletions(-)
drivers/net/ethernet/arc/emac_main.c +31 -22
@@ -210,39 +210,48 @@ static int arc_emac_rx(struct net_devicecontinue ; } - pktlen = info &LEN_MASK ; - stats->rx_packets++; - stats->rx_bytes += pktlen; - skb = rx_buff->skb; -skb_put (skb, pktlen); - skb->dev = ndev; - skb->protocol =eth_type_trans (skb, ndev); - -dma_unmap_single (&ndev->dev,dma_unmap_addr (rx_buff, addr), -dma_unmap_len (rx_buff, len),DMA_FROM_DEVICE ); - -/* Prepare the BD for next cycle */ - rx_buff->skb =netdev_alloc_skb_ip_align (ndev, -EMAC_BUFFER_SIZE ); -if (unlikely (!rx_buff->skb)) { +/* Prepare the BD for next cycle. netif_receive_skb() +* only if new skb was allocated and mapped to avoid holes +* in the RX fifo. +*/ + skb =netdev_alloc_skb_ip_align (ndev,EMAC_BUFFER_SIZE ); +if (unlikely (!skb)) { +if (net_ratelimit ()) +netdev_err (ndev,"cannot allocate skb\n" ); +/* Return ownership to EMAC */ + rxbd->info =cpu_to_le32 (FOR_EMAC |EMAC_BUFFER_SIZE ); stats->rx_errors++; -/* Because receive_skb is below, increment rx_dropped */ stats->rx_dropped++;continue ; } -/* receive_skb only if new skb was allocated to avoid holes */ -netif_receive_skb (skb); - - addr =dma_map_single (&ndev->dev, (void *)rx_buff->skb->data, + addr =dma_map_single (&ndev->dev, (void *)skb->data,EMAC_BUFFER_SIZE ,DMA_FROM_DEVICE );if (dma_mapping_error (&ndev->dev, addr)) {if (net_ratelimit ()) -netdev_err (ndev,"cannot dma map\n" ); -dev_kfree_skb (rx_buff->skb); +netdev_err (ndev,"cannot map dma buffer\n" ); +dev_kfree_skb (skb); +/* Return ownership to EMAC */ + rxbd->info =cpu_to_le32 (FOR_EMAC |EMAC_BUFFER_SIZE ); stats->rx_errors++; + stats->rx_dropped++;continue ; } + +/* unmap previosly mapped skb */ +dma_unmap_single (&ndev->dev,dma_unmap_addr (rx_buff, addr), +dma_unmap_len (rx_buff, len),DMA_FROM_DEVICE ); + + pktlen = info &LEN_MASK ; + stats->rx_packets++; + stats->rx_bytes += pktlen; +skb_put (rx_buff->skb, pktlen); + rx_buff->skb->dev = ndev; + rx_buff->skb->protocol =eth_type_trans (rx_buff->skb, ndev); + +netif_receive_skb (rx_buff->skb); + + rx_buff->skb = skb;dma_unmap_addr_set (rx_buff, addr, addr);dma_unmap_len_set (rx_buff, len,EMAC_BUFFER_SIZE );
Patches currently in stable-queue which might be from [email protected] are
queue-4.14/net-arc_emac-fix-arc_emac_rx-error-paths.patch