diff options
author | Ioana Radulescu <ruxandra.radulescu@freescale.com> | 2013-06-21 20:51:00 (GMT) |
---|---|---|
committer | Fleming Andrew-AFLEMING <AFLEMING@freescale.com> | 2013-07-11 22:45:06 (GMT) |
commit | 1fd9018f9c6a10932e86285c256bfdf50da8c0c1 (patch) | |
tree | 480b68d33ea35fbe25516dc3c8c0d282e5f1399e /drivers/net | |
parent | e5d63f8155c8b744662b0208f43cfeb502cacfc0 (diff) | |
download | linux-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.c | 34 |
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; |