From 2588e94f31578de88b7371c88e5637d52101cb1b Mon Sep 17 00:00:00 2001 From: Ioana Radulescu Date: Fri, 23 Aug 2013 12:01:27 +0300 Subject: dpaa_eth: Fix draining of buffer pools When draining buffers in batches of eight, we must take into account the fact that BMan will return an error code if there are less than eight buffers left in the pool; when this happens, drain the remaining buffers one by one. And since we're at buffer pool cleanup, make sure allocated bpools get freed in case of errors inside the probe function. Signed-off-by: Ioana Radulescu Change-Id: I9b2516ea76a19487a2f75412722ea21e67247ed2 Reviewed-on: http://git.am.freescale.net:8181/4191 Tested-by: Review Code-CDREVIEW Reviewed-by: Bucur Madalin-Cristian-B32716 Reviewed-by: Rivera Jose-B46482 Reviewed-on: http://git.am.freescale.net:8181/4471 Reviewed-by: Sovaiala Cristian-Constantin-B39531 diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth.c index 2981467..c1b400a 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth.c @@ -704,7 +704,7 @@ dpaa_eth_priv_probe(struct platform_device *_of_dev) net_dev = alloc_etherdev_mq(sizeof(*priv), DPAA_ETH_TX_QUEUES); if (!net_dev) { dev_err(dev, "alloc_etherdev_mq() failed\n"); - return -ENOMEM; + goto alloc_etherdev_mq_failed; } /* Do this here, so we can be verbose early */ @@ -862,6 +862,8 @@ mac_probe_failed: dev_set_drvdata(dev, NULL); if (net_dev) free_netdev(net_dev); +alloc_etherdev_mq_failed: + devm_kfree(dev, dpa_bp); return err; } diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c index 392ec1a..fc7433e 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c @@ -474,6 +474,8 @@ int __cold dpa_remove(struct platform_device *of_dev) free_percpu(priv->percpu_priv); dpa_bp_free(priv, priv->dpa_bp); + devm_kfree(dev, priv->dpa_bp); + if (priv->buf_layout) devm_kfree(dev, priv->buf_layout); @@ -710,13 +712,25 @@ pdev_register_failed: void dpa_bp_drain(struct dpa_bp *bp) { - int num; + int ret, num = 8; do { struct bm_buffer bmb[8]; int i; - num = bman_acquire(bp->pool, bmb, 8, 0); + ret = bman_acquire(bp->pool, bmb, 8, 0); + if (ret < 0) { + if (num == 8) { + /* we have less than 8 buffers left; + * drain them one by one + */ + num = 1; + continue; + } else { + /* Pool is fully drained */ + break; + } + } for (i = 0; i < num; i++) { dma_addr_t addr = bm_buf_addr(&bmb[i]); @@ -726,7 +740,7 @@ void dpa_bp_drain(struct dpa_bp *bp) bp->free_buf_cb(phys_to_virt(addr)); } - } while (num == 8); + } while (ret > 0); } static void __cold __attribute__((nonnull)) -- cgit v0.10.2