From b0dbadb589c333361e388ece255626531ce60fd2 Mon Sep 17 00:00:00 2001 From: Ioana Radulescu Date: Fri, 21 Jun 2013 20:51:00 +0000 Subject: 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 Signed-off-by: Bogdan Hamciuc Signed-off-by: Madalin Bucur Change-Id: Ia7cd0979adfa2d5c6f5be88017ed2bd0bfd202f8 Reviewed-on: http://git.am.freescale.net:8181/3335 Reviewed-by: Radulescu Ruxandra Ioana-B05472 Tested-by: Review Code-CDREVIEW Reviewed-by: Sovaiala Cristian-Constantin-B39531 Reviewed-by: Fleming Andrew-AFLEMING diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth.c index cca3383..d09d6b9 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth.c @@ -345,8 +345,14 @@ priv_rx_error_dqrr(struct qman_portal *portal, return qman_cb_dqrr_stop; } - dpaa_eth_refill_bpools(percpu_priv); - _dpa_rx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid); + if (unlikely(dpaa_eth_refill_bpools(percpu_priv))) + /* 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); + else + _dpa_rx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid); return qman_cb_dqrr_consume; } @@ -376,8 +382,15 @@ priv_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); - _dpa_rx(net_dev, priv, percpu_priv, &dq->fd, fq->fqid); + + if (unlikely(dpaa_eth_refill_bpools(percpu_priv))) + /* 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); + else + _dpa_rx(net_dev, priv, percpu_priv, &dq->fd, fq->fqid); return qman_cb_dqrr_consume; } diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth.h b/drivers/net/ethernet/freescale/dpa/dpaa_eth.h index e3e5d69..b3f4ec2 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth.h +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth.h @@ -451,7 +451,7 @@ struct fm_port_fqs { /* functions with different implementation for SG and non-SG: */ void dpa_make_private_pool(struct dpa_bp *dpa_bp); -void dpaa_eth_refill_bpools(struct dpa_percpu_priv_s *percpu_priv); +int dpaa_eth_refill_bpools(struct dpa_percpu_priv_s *percpu_priv); void __hot _dpa_rx(struct net_device *net_dev, const struct dpa_priv_s *priv, struct dpa_percpu_priv_s *percpu_priv, diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_non_sg.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_non_sg.c index 1d4d323..42a0448 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_non_sg.c +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_non_sg.c @@ -153,7 +153,7 @@ void dpa_make_private_pool(struct dpa_bp *dpa_bp) /* Add buffers/(skbuffs) for Rx processing whenever bpool count falls below * REFILL_THRESHOLD. */ -void dpaa_eth_refill_bpools(struct dpa_percpu_priv_s *percpu_priv) +int dpaa_eth_refill_bpools(struct dpa_percpu_priv_s *percpu_priv) { int *countptr = percpu_priv->dpa_bp_count; int count = *countptr; @@ -169,6 +169,8 @@ void dpaa_eth_refill_bpools(struct dpa_percpu_priv_s *percpu_priv) for (i = count; i < CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT; i += 8) dpa_bp_add_8(dpa_bp, cpu); } + + return 0; } /* Cleanup function for outgoing frame descriptors that were built on Tx path, diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c index 32086d4..7f0e870 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c @@ -159,7 +159,7 @@ void dpa_make_private_pool(struct dpa_bp *dpa_bp) * Add buffers/(pages) for Rx processing whenever bpool count falls below * REFILL_THRESHOLD. */ -void dpaa_eth_refill_bpools(struct dpa_percpu_priv_s *percpu_priv) +int dpaa_eth_refill_bpools(struct dpa_percpu_priv_s *percpu_priv) { int *countptr = percpu_priv->dpa_bp_count; int count = *countptr; @@ -179,6 +179,11 @@ void dpaa_eth_refill_bpools(struct dpa_percpu_priv_s *percpu_priv) count += new_pages; } *countptr = count; + + if (unlikely(*countptr < CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT)) + return -ENOMEM; + + return 0; } /* Cleanup function for outgoing frame descriptors that were built on Tx path, -- cgit v0.10.2