summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIoana Radulescu <ruxandra.radulescu@nxp.com>2017-09-15 16:31:22 (GMT)
committerXie Xiaobo <xiaobo.xie@nxp.com>2017-12-12 07:32:41 (GMT)
commit0f10e8de08e3a60fd9ecee149dfd6aecc6e973bc (patch)
tree792a2a488c50de14a4013abba52c26bd9181f9a8
parentd5671827e9a1660418493a1767fbe6f63bb69e5c (diff)
downloadlinux-0f10e8de08e3a60fd9ecee149dfd6aecc6e973bc.tar.xz
staging: fsl-dpaa2/eth: Account for Rx FD buffers on error path
On Rx path, if we fail to build an skb from the incoming FD, we still need to update the channel buffer count accordingly, otherwise we risk depleting the pool while the software counter still sees available buffers. Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com> Integrated-by: Guanhua Gao <guanhua.gao@nxp.com>
-rw-r--r--drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
index 3fbb614..9d759c8 100644
--- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
@@ -137,6 +137,8 @@ static struct sk_buff *build_linear_skb(struct dpaa2_eth_priv *priv,
u16 fd_offset = dpaa2_fd_get_offset(fd);
u32 fd_length = dpaa2_fd_get_len(fd);
+ ch->buf_count--;
+
skb = build_skb(fd_vaddr, DPAA2_ETH_SKB_SIZE);
if (unlikely(!skb))
return NULL;
@@ -144,8 +146,6 @@ static struct sk_buff *build_linear_skb(struct dpaa2_eth_priv *priv,
skb_reserve(skb, fd_offset);
skb_put(skb, fd_length);
- ch->buf_count--;
-
return skb;
}
@@ -183,7 +183,7 @@ static struct sk_buff *build_frag_skb(struct dpaa2_eth_priv *priv,
/* We build the skb around the first data buffer */
skb = build_skb(sg_vaddr, DPAA2_ETH_SKB_SIZE);
if (unlikely(!skb))
- return NULL;
+ goto err_build;
sg_offset = dpaa2_sg_get_offset(sge);
skb_reserve(skb, sg_offset);
@@ -214,6 +214,17 @@ static struct sk_buff *build_frag_skb(struct dpaa2_eth_priv *priv,
ch->buf_count -= i + 2;
return skb;
+
+err_build:
+ /* We still need to subtract the buffers used by this FD from our
+ * software counter
+ */
+ for (i = 0; i < DPAA2_ETH_MAX_SG_ENTRIES; i++)
+ if (dpaa2_sg_is_final(&sgt[i]))
+ break;
+ ch->buf_count -= i + 2;
+
+ return NULL;
}
static void free_bufs(struct dpaa2_eth_priv *priv, u64 *buf_array, int count)