[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <VI1PR04MB68009F16CAA80DCEBFA8F170E6709@VI1PR04MB6800.eurprd04.prod.outlook.com>
Date: Thu, 9 Dec 2021 01:31:52 +0000
From: Joakim Zhang <qiangqing.zhang@....com>
To: Xiaoliang Yang <xiaoliang.yang_1@....com>,
"davem@...emloft.net" <davem@...emloft.net>,
"netdev@...r.kernel.org" <netdev@...r.kernel.org>,
"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>
CC: "kuba@...nel.org" <kuba@...nel.org>,
"peppe.cavallaro@...com" <peppe.cavallaro@...com>,
"alexandre.torgue@...s.st.com" <alexandre.torgue@...s.st.com>,
"joabreu@...opsys.com" <joabreu@...opsys.com>,
Yannick Vignon <yannick.vignon@....com>,
"boon.leong.ong@...el.com" <boon.leong.ong@...el.com>,
"Jose.Abreu@...opsys.com" <Jose.Abreu@...opsys.com>,
"mst@...hat.com" <mst@...hat.com>,
"sonic.zhang@...log.com" <sonic.zhang@...log.com>,
"Joao.Pinto@...opsys.com" <Joao.Pinto@...opsys.com>,
Mingkai Hu <mingkai.hu@....com>, Leo Li <leoyang.li@....com>,
Xiaoliang Yang <xiaoliang.yang_1@....com>
Subject: RE: [PATCH net-next] net: stmmac: bump tc when get underflow error
from DMA descriptor
> -----Original Message-----
> From: Xiaoliang Yang <xiaoliang.yang_1@....com>
> Sent: 2021年12月8日 18:07
> To: davem@...emloft.net; netdev@...r.kernel.org;
> linux-kernel@...r.kernel.org
> Cc: kuba@...nel.org; Joakim Zhang <qiangqing.zhang@....com>;
> peppe.cavallaro@...com; alexandre.torgue@...s.st.com;
> joabreu@...opsys.com; Yannick Vignon <yannick.vignon@....com>;
> boon.leong.ong@...el.com; Jose.Abreu@...opsys.com; mst@...hat.com;
> sonic.zhang@...log.com; Joao.Pinto@...opsys.com; Mingkai Hu
> <mingkai.hu@....com>; Leo Li <leoyang.li@....com>; Xiaoliang Yang
> <xiaoliang.yang_1@....com>
> Subject: [PATCH net-next] net: stmmac: bump tc when get underflow error
> from DMA descriptor
>
> In DMA threshold mode, frame underflow errors may sometimes occur
> when the TC(threshold control) value is not enough. The TC value need to be
> bumped up in this case.
>
> There is no underflow interrupt bit on DMA_CH(#i)_Status of dwmac4, so
> the DMA threshold cannot be bumped up in stmmac_dma_interrupt(). The
> i.mx8mp board observed an underflow error while running NFS boot, the
> NFS rootfs could not be mounted.
>
> The underflow error can be got from the DMA descriptor TDES3 on dwmac4.
> This patch bump up tc value once underflow error is got from TDES3.
>
> Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@....com>
5 queues with FIFO cut-through mode can work well after applying this patch.
Tested-by/Reviewed-by: Joakim Zhang <qiangqing.zhang@....com>
Best Regards,
Joakim Zhang
> ---
> drivers/net/ethernet/stmicro/stmmac/common.h | 1 +
> .../ethernet/stmicro/stmmac/dwmac4_descs.c | 8 +--
> .../net/ethernet/stmicro/stmmac/stmmac_main.c | 51 ++++++++-----------
> 3 files changed, 27 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h
> b/drivers/net/ethernet/stmicro/stmmac/common.h
> index 9160f9ed363a..6b5d96bced47 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/common.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
> @@ -317,6 +317,7 @@ enum tx_frame_status {
> tx_not_ls = 0x1,
> tx_err = 0x2,
> tx_dma_own = 0x4,
> + tx_err_bump_tc = 0x8,
> };
>
> enum dma_irq_status {
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
> b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
> index cbf4429fb1d2..d3b4765c1a5b 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
> @@ -32,6 +32,8 @@ static int dwmac4_wrback_get_tx_status(void *data,
> struct stmmac_extra_stats *x,
> return tx_not_ls;
>
> if (unlikely(tdes3 & TDES3_ERROR_SUMMARY)) {
> + ret = tx_err;
> +
> if (unlikely(tdes3 & TDES3_JABBER_TIMEOUT))
> x->tx_jabber++;
> if (unlikely(tdes3 & TDES3_PACKET_FLUSHED)) @@ -53,16 +55,16
> @@ static int dwmac4_wrback_get_tx_status(void *data, struct
> stmmac_extra_stats *x,
> if (unlikely(tdes3 & TDES3_EXCESSIVE_DEFERRAL))
> x->tx_deferred++;
>
> - if (unlikely(tdes3 & TDES3_UNDERFLOW_ERROR))
> + if (unlikely(tdes3 & TDES3_UNDERFLOW_ERROR)) {
> x->tx_underflow++;
> + ret |= tx_err_bump_tc;
> + }
>
> if (unlikely(tdes3 & TDES3_IP_HDR_ERROR))
> x->tx_ip_header_error++;
>
> if (unlikely(tdes3 & TDES3_PAYLOAD_ERROR))
> x->tx_payload_error++;
> -
> - ret = tx_err;
> }
>
> if (unlikely(tdes3 & TDES3_DEFERRED))
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index 4e05c1d92935..7e3e1bc0f61d 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -132,6 +132,8 @@ static irqreturn_t stmmac_msi_intr_tx(int irq, void
> *data); static irqreturn_t stmmac_msi_intr_rx(int irq, void *data); static
> void stmmac_tx_timer_arm(struct stmmac_priv *priv, u32 queue); static
> void stmmac_flush_tx_descriptors(struct stmmac_priv *priv, int queue);
> +static void stmmac_set_dma_operation_mode(struct stmmac_priv *priv,
> u32 txmode,
> + u32 rxmode, u32 chan);
>
> #ifdef CONFIG_DEBUG_FS
> static const struct net_device_ops stmmac_netdev_ops; @@ -2466,6
> +2468,21 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32
> queue, u32 budget)
> return !!budget && work_done;
> }
>
> +static void stmmac_bump_dma_threshold(struct stmmac_priv *priv, u32
> +chan) {
> + if (unlikely(priv->xstats.threshold != SF_DMA_MODE) && tc <= 256) {
> + tc += 64;
> +
> + if (priv->plat->force_thresh_dma_mode)
> + stmmac_set_dma_operation_mode(priv, tc, tc, chan);
> + else
> + stmmac_set_dma_operation_mode(priv, tc, SF_DMA_MODE,
> + chan);
> +
> + priv->xstats.threshold = tc;
> + }
> +}
> +
> /**
> * stmmac_tx_clean - to manage the transmission completion
> * @priv: driver private structure
> @@ -2531,6 +2548,8 @@ static int stmmac_tx_clean(struct stmmac_priv
> *priv, int budget, u32 queue)
> /* ... verify the status error condition */
> if (unlikely(status & tx_err)) {
> priv->dev->stats.tx_errors++;
> + if (unlikely(status & tx_err_bump_tc))
> + stmmac_bump_dma_threshold(priv, queue);
> } else {
> priv->dev->stats.tx_packets++;
> priv->xstats.tx_pkt_n++;
> @@ -2781,21 +2800,7 @@ static void stmmac_dma_interrupt(struct
> stmmac_priv *priv)
> for (chan = 0; chan < tx_channel_count; chan++) {
> if (unlikely(status[chan] & tx_hard_error_bump_tc)) {
> /* Try to bump up the dma threshold on this failure */
> - if (unlikely(priv->xstats.threshold != SF_DMA_MODE) &&
> - (tc <= 256)) {
> - tc += 64;
> - if (priv->plat->force_thresh_dma_mode)
> - stmmac_set_dma_operation_mode(priv,
> - tc,
> - tc,
> - chan);
> - else
> - stmmac_set_dma_operation_mode(priv,
> - tc,
> - SF_DMA_MODE,
> - chan);
> - priv->xstats.threshold = tc;
> - }
> + stmmac_bump_dma_threshold(priv, chan);
> } else if (unlikely(status[chan] == tx_hard_error)) {
> stmmac_tx_err(priv, chan);
> }
> @@ -5745,21 +5750,7 @@ static irqreturn_t stmmac_msi_intr_tx(int irq, void
> *data)
>
> if (unlikely(status & tx_hard_error_bump_tc)) {
> /* Try to bump up the dma threshold on this failure */
> - if (unlikely(priv->xstats.threshold != SF_DMA_MODE) &&
> - tc <= 256) {
> - tc += 64;
> - if (priv->plat->force_thresh_dma_mode)
> - stmmac_set_dma_operation_mode(priv,
> - tc,
> - tc,
> - chan);
> - else
> - stmmac_set_dma_operation_mode(priv,
> - tc,
> - SF_DMA_MODE,
> - chan);
> - priv->xstats.threshold = tc;
> - }
> + stmmac_bump_dma_threshold(priv, chan);
> } else if (unlikely(status == tx_hard_error)) {
> stmmac_tx_err(priv, chan);
> }
> --
> 2.17.1
Powered by blists - more mailing lists