summaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
authorIoana Radulescu <ruxandra.radulescu@freescale.com>2013-06-21 20:51:00 (GMT)
committerFleming Andrew-AFLEMING <AFLEMING@freescale.com>2013-07-11 22:45:06 (GMT)
commit1fd9018f9c6a10932e86285c256bfdf50da8c0c1 (patch)
tree480b68d33ea35fbe25516dc3c8c0d282e5f1399e /drivers/net
parente5d63f8155c8b744662b0208f43cfeb502cacfc0 (diff)
downloadlinux-fsl-qoriq-1fd9018f9c6a10932e86285c256bfdf50da8c0c1.tar.xz
dpaa_eth: Handle buffer pool depletion
If the system gets into an out-of-memory state, we are unable to refill the default buffer pool with new buffers. While this lasts, just release any incoming frame back to the pool without further processing. Signed-off-by: Ioana Radulescu <ruxandra.radulescu@freescale.com> Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@freescale.com> Change-Id: Ia7fe59c44aa371f81540b45d197aef896b6d6b3a Reviewed-on: http://git.am.freescale.net:8181/3050 Reviewed-by: Bucur Madalin-Cristian-B32716 <madalin.bucur@freescale.com> Reviewed-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com> Tested-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth.c
index 2bd1f77..55edca4 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth.c
@@ -390,13 +390,14 @@ static void dpaa_eth_seed_pool(struct dpa_bp *bp)
* Add buffers/pages/skbuffs for Rx processing whenever bpool count falls below
* REFILL_THRESHOLD.
*/
-static void dpaa_eth_refill_bpools(struct dpa_percpu_priv_s *percpu_priv)
+static int dpaa_eth_refill_bpools(struct dpa_percpu_priv_s *percpu_priv)
{
int *countptr = percpu_priv->dpa_bp_count;
int count = *countptr;
const struct dpa_bp *dpa_bp = percpu_priv->dpa_bp;
- int new_pages;
+ int new_pages __maybe_unused;
#ifndef CONFIG_FSL_DPAA_ETH_SG_SUPPORT
+
/* this function is called in softirq context;
* no need to protect smp_processor_id() on RT kernel
*/
@@ -422,7 +423,12 @@ static void dpaa_eth_refill_bpools(struct dpa_percpu_priv_s *percpu_priv)
count += new_pages;
}
*countptr = count;
+
+ if (*countptr < CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT)
+ return -ENOMEM;
#endif
+
+ return 0;
}
static int dpa_make_shared_port_pool(struct dpa_bp *bp)
@@ -2193,6 +2199,7 @@ ingress_rx_error_dqrr(struct qman_portal *portal,
struct net_device *net_dev;
struct dpa_priv_s *priv;
struct dpa_percpu_priv_s *percpu_priv;
+ int err;
net_dev = ((struct dpa_fq *)fq)->net_dev;
priv = netdev_priv(net_dev);
@@ -2204,7 +2211,16 @@ ingress_rx_error_dqrr(struct qman_portal *portal,
return qman_cb_dqrr_stop;
}
- dpaa_eth_refill_bpools(percpu_priv);
+ err = dpaa_eth_refill_bpools(percpu_priv);
+ if (err) {
+ /* Unable to refill the buffer pool due to insufficient
+ * system memory. Just release the frame back into the pool,
+ * otherwise we'll soon end up with an empty buffer pool.
+ */
+ dpa_fd_release(net_dev, &dq->fd);
+ return qman_cb_dqrr_consume;
+ }
+
_dpa_rx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
return qman_cb_dqrr_consume;
@@ -2352,6 +2368,7 @@ ingress_rx_default_dqrr(struct qman_portal *portal,
struct net_device *net_dev;
struct dpa_priv_s *priv;
struct dpa_percpu_priv_s *percpu_priv;
+ int err;
net_dev = ((struct dpa_fq *)fq)->net_dev;
priv = netdev_priv(net_dev);
@@ -2368,7 +2385,16 @@ ingress_rx_default_dqrr(struct qman_portal *portal,
}
/* Vale of plenty: make sure we didn't run out of buffers */
- dpaa_eth_refill_bpools(percpu_priv);
+ err = dpaa_eth_refill_bpools(percpu_priv);
+ if (err) {
+ /* Unable to refill the buffer pool due to insufficient
+ * system memory. Just release the frame back into the pool,
+ * otherwise we'll soon end up with an empty buffer pool.
+ */
+ dpa_fd_release(net_dev, &dq->fd);
+ return qman_cb_dqrr_consume;
+ }
+
_dpa_rx(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
return qman_cb_dqrr_consume;