From: Russell King <rmk+kernel@arm.linux.org.uk> To: "David S. Miller" <davem@davemloft.net> Cc: netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH A 09/12] net: fec: make rx skb handling more robust Date: Tue, 08 Jul 2014 00:23:14 +0100 [thread overview] Message-ID: <E1X4IFe-0004xE-Rp@rmk-PC.arm.linux.org.uk> (raw) In-Reply-To: <20140707232148.GG21766@n2100.arm.linux.org.uk> Allocate, and then map the receive skb before writing any data to the ring descriptor or storing the skb. When freeing the receive ring entries, unmap and free the skb, and then clear the stored skb pointer. This means we have ring data and skb pointer in one of two states: either both fully setup, or nothing setup. This simplifies the cleanup, as we can use just the skb pointer to indicate whether the descriptor is setup, and thus avoids potentially calling dma_unmap_single() on a DMA error value. Acked-by: Fugang Duan <B38611@freescale.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- drivers/net/ethernet/freescale/fec_main.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 309aa2ff8cc9..70853a59627a 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -2066,12 +2066,12 @@ static void fec_enet_free_buffers(struct net_device *ndev) bdp = fep->rx_bd_base; for (i = 0; i < fep->rx_ring_size; i++) { skb = fep->rx_skbuff[i]; - - if (bdp->cbd_bufaddr) + fep->rx_skbuff[i] = NULL; + if (skb) { dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr, FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE); - if (skb) dev_kfree_skb(skb); + } bdp = fec_enet_get_nextdesc(bdp, fep); } @@ -2089,21 +2089,26 @@ static int fec_enet_alloc_buffers(struct net_device *ndev) bdp = fep->rx_bd_base; for (i = 0; i < fep->rx_ring_size; i++) { + dma_addr_t addr; + skb = netdev_alloc_skb(ndev, FEC_ENET_RX_FRSIZE); if (!skb) { fec_enet_free_buffers(ndev); return -ENOMEM; } - fep->rx_skbuff[i] = skb; - bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, skb->data, + addr = dma_map_single(&fep->pdev->dev, skb->data, FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE); - if (dma_mapping_error(&fep->pdev->dev, bdp->cbd_bufaddr)) { + if (dma_mapping_error(&fep->pdev->dev, addr)) { + dev_kfree_skb(skb); fec_enet_free_buffers(ndev); if (net_ratelimit()) netdev_err(ndev, "Rx DMA memory map failed\n"); return -ENOMEM; } + + fep->rx_skbuff[i] = skb; + bdp->cbd_bufaddr = addr; bdp->cbd_sc = BD_ENET_RX_EMPTY; if (fep->bufdesc_ex) { -- 1.8.3.1
WARNING: multiple messages have this Message-ID (diff)
From: rmk+kernel@arm.linux.org.uk (Russell King) To: linux-arm-kernel@lists.infradead.org Subject: [PATCH A 09/12] net: fec: make rx skb handling more robust Date: Tue, 08 Jul 2014 00:23:14 +0100 [thread overview] Message-ID: <E1X4IFe-0004xE-Rp@rmk-PC.arm.linux.org.uk> (raw) In-Reply-To: <20140707232148.GG21766@n2100.arm.linux.org.uk> Allocate, and then map the receive skb before writing any data to the ring descriptor or storing the skb. When freeing the receive ring entries, unmap and free the skb, and then clear the stored skb pointer. This means we have ring data and skb pointer in one of two states: either both fully setup, or nothing setup. This simplifies the cleanup, as we can use just the skb pointer to indicate whether the descriptor is setup, and thus avoids potentially calling dma_unmap_single() on a DMA error value. Acked-by: Fugang Duan <B38611@freescale.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- drivers/net/ethernet/freescale/fec_main.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 309aa2ff8cc9..70853a59627a 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -2066,12 +2066,12 @@ static void fec_enet_free_buffers(struct net_device *ndev) bdp = fep->rx_bd_base; for (i = 0; i < fep->rx_ring_size; i++) { skb = fep->rx_skbuff[i]; - - if (bdp->cbd_bufaddr) + fep->rx_skbuff[i] = NULL; + if (skb) { dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr, FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE); - if (skb) dev_kfree_skb(skb); + } bdp = fec_enet_get_nextdesc(bdp, fep); } @@ -2089,21 +2089,26 @@ static int fec_enet_alloc_buffers(struct net_device *ndev) bdp = fep->rx_bd_base; for (i = 0; i < fep->rx_ring_size; i++) { + dma_addr_t addr; + skb = netdev_alloc_skb(ndev, FEC_ENET_RX_FRSIZE); if (!skb) { fec_enet_free_buffers(ndev); return -ENOMEM; } - fep->rx_skbuff[i] = skb; - bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, skb->data, + addr = dma_map_single(&fep->pdev->dev, skb->data, FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE); - if (dma_mapping_error(&fep->pdev->dev, bdp->cbd_bufaddr)) { + if (dma_mapping_error(&fep->pdev->dev, addr)) { + dev_kfree_skb(skb); fec_enet_free_buffers(ndev); if (net_ratelimit()) netdev_err(ndev, "Rx DMA memory map failed\n"); return -ENOMEM; } + + fep->rx_skbuff[i] = skb; + bdp->cbd_bufaddr = addr; bdp->cbd_sc = BD_ENET_RX_EMPTY; if (fep->bufdesc_ex) { -- 1.8.3.1
next prev parent reply other threads:[~2014-07-07 23:23 UTC|newest] Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top 2014-07-07 23:21 [PATCH A 00/12] Freescale ethernet driver updates Russell King - ARM Linux 2014-07-07 23:21 ` Russell King - ARM Linux 2014-07-07 23:22 ` [PATCH A 01/12] net: fec: iMX6 FEC does not support half-duplex gigabit Russell King 2014-07-07 23:22 ` Russell King 2014-07-08 16:52 ` Sergei Shtylyov 2014-07-08 16:52 ` Sergei Shtylyov 2014-07-07 23:22 ` [PATCH A 02/12] net: fec: fix ethtool set_pauseparam duplex bug Russell King 2014-07-07 23:22 ` Russell King 2014-07-07 23:22 ` [PATCH A 03/12] net: fec: fix interrupt handling races Russell King 2014-07-07 23:22 ` Russell King 2014-07-07 23:22 ` [PATCH A 04/12] net: fec: use netif_tx_disable() rather than netif_stop_queue() Russell King 2014-07-07 23:22 ` Russell King 2014-07-07 23:22 ` [PATCH A 05/12] net: fec: remove checking for NULL phy_dev in fec_enet_close() Russell King 2014-07-07 23:22 ` Russell King 2014-07-07 23:22 ` [PATCH A 06/12] net: fec: ensure that a disconnected phy isn't configured Russell King 2014-07-07 23:22 ` Russell King 2014-07-07 23:23 ` [PATCH A 07/12] net: fec: stop the phy before shutting down the MAC Russell King 2014-07-07 23:23 ` Russell King 2014-07-07 23:23 ` [PATCH A 08/12] net: fec: remove useless fep->opened Russell King 2014-07-07 23:23 ` Russell King 2014-07-07 23:23 ` Russell King [this message] 2014-07-07 23:23 ` [PATCH A 09/12] net: fec: make rx skb handling more robust Russell King 2014-07-07 23:23 ` [PATCH A 10/12] net: fec: clean up transmit descriptor setup Russell King 2014-07-07 23:23 ` Russell King 2014-07-07 23:23 ` [PATCH A 11/12] net: fec: ensure fec_enet_free_buffers() properly cleans the rings Russell King 2014-07-07 23:23 ` Russell King 2014-07-07 23:23 ` [PATCH A 12/12] net: fec: fix missing kmalloc() failure check in fec_enet_alloc_buffers() Russell King 2014-07-07 23:23 ` Russell King 2014-07-08 4:22 ` [PATCH A 00/12] Freescale ethernet driver updates David Miller 2014-07-08 4:22 ` David Miller
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=E1X4IFe-0004xE-Rp@rmk-PC.arm.linux.org.uk \ --to=rmk+kernel@arm.linux.org.uk \ --cc=davem@davemloft.net \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=netdev@vger.kernel.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.