Message ID | d95413e44c97d4692e72cec13a75f894abeb6998.1699897370.git.baruch@tkos.co.il (mailing list archive) |
---|---|
State | Accepted |
Commit | b6cb4541853c7ee512111b0e7ddf3cb66c99c137 |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | [net,1/2] net: stmmac: fix rx budget limit check | expand |
On Mon, 13 Nov 2023 19:42:50 +0200 Baruch Siach wrote: > dma_rx_size can be set as low as 64. Rx budget might be higher than > that. Make sure to not overrun allocated rx buffers when budget is > larger. > > Leave one descriptor unused to avoid wrap around of 'dirty_rx' vs > 'cur_rx'. Can we get a Fixes tag for this one as well?
Hi Jakub, On Mon, Nov 13 2023, Jakub Kicinski wrote: > On Mon, 13 Nov 2023 19:42:50 +0200 Baruch Siach wrote: >> dma_rx_size can be set as low as 64. Rx budget might be higher than >> that. Make sure to not overrun allocated rx buffers when budget is >> larger. >> >> Leave one descriptor unused to avoid wrap around of 'dirty_rx' vs >> 'cur_rx'. > > Can we get a Fixes tag for this one as well? I believe it goes back to the commit that introduced the driver. Fixes: 47dd7a540b8a ("net: add support for STMicroelectronics Ethernet controllers.") Should I resend with the Fixes tag? baruch
On Mon, Nov 13, 2023 at 07:42:50PM +0200, Baruch Siach wrote: > dma_rx_size can be set as low as 64. Rx budget might be higher than > that. Make sure to not overrun allocated rx buffers when budget is > larger. > > Leave one descriptor unused to avoid wrap around of 'dirty_rx' vs > 'cur_rx'. Have you ever met the denoted problem? I am asking because what you say can happen only if the incoming traffic overruns the Rx-buffer, otherwise the loop will break on the first found DMA-own descriptor. But if that happens AFAICS the result will likely to be fatal because the stmmac_rx() method will try to handle the already handled and not yet recycled descriptor with no buffers assigned. So after adding the Fixes tag feel tree to add: Reviewed-by: Serge Semin <fancer.lancer@gmail.com> -Serge(y) > > Signed-off-by: Baruch Siach <baruch@tkos.co.il> > --- > drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c > index f28838c8cdb3..2afb2bd25977 100644 > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c > @@ -5293,6 +5293,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) > > dma_dir = page_pool_get_dma_dir(rx_q->page_pool); > buf_sz = DIV_ROUND_UP(priv->dma_conf.dma_buf_sz, PAGE_SIZE) * PAGE_SIZE; > + limit = min(priv->dma_conf.dma_rx_size - 1, (unsigned int)limit); > > if (netif_msg_rx_status(priv)) { > void *rx_head; > -- > 2.42.0 > >
Hi Serge, On Tue, Nov 14 2023, Serge Semin wrote: > On Mon, Nov 13, 2023 at 07:42:50PM +0200, Baruch Siach wrote: >> dma_rx_size can be set as low as 64. Rx budget might be higher than >> that. Make sure to not overrun allocated rx buffers when budget is >> larger. >> >> Leave one descriptor unused to avoid wrap around of 'dirty_rx' vs >> 'cur_rx'. > > Have you ever met the denoted problem? I am asking because what you > say can happen only if the incoming traffic overruns the Rx-buffer, > otherwise the loop will break on the first found DMA-own descriptor. > But if that happens AFAICS the result will likely to be fatal because > the stmmac_rx() method will try to handle the already handled and not > yet recycled descriptor with no buffers assigned. I have encountered this issue. When stmmac_rx() consumes all dma_rx_size descriptors in one go, dirty_rx == cur_rx, which leads stmmac_rx_dirty() to return zero. That in turn makes stmmac_rx_refill() skip stmmac_set_rx_owner() so that Rx hangs completely. > So after adding the Fixes tag feel tree to add: > Reviewed-by: Serge Semin <fancer.lancer@gmail.com> Thanks, baruch > -Serge(y) > >> >> Signed-off-by: Baruch Siach <baruch@tkos.co.il> >> --- >> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 1 + >> 1 file changed, 1 insertion(+) >> >> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c >> index f28838c8cdb3..2afb2bd25977 100644 >> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c >> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c >> @@ -5293,6 +5293,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) >> >> dma_dir = page_pool_get_dma_dir(rx_q->page_pool); >> buf_sz = DIV_ROUND_UP(priv->dma_conf.dma_buf_sz, PAGE_SIZE) * PAGE_SIZE; >> + limit = min(priv->dma_conf.dma_rx_size - 1, (unsigned int)limit); >> >> if (netif_msg_rx_status(priv)) { >> void *rx_head; >> -- >> 2.42.0 >> >>
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index f28838c8cdb3..2afb2bd25977 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -5293,6 +5293,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) dma_dir = page_pool_get_dma_dir(rx_q->page_pool); buf_sz = DIV_ROUND_UP(priv->dma_conf.dma_buf_sz, PAGE_SIZE) * PAGE_SIZE; + limit = min(priv->dma_conf.dma_rx_size - 1, (unsigned int)limit); if (netif_msg_rx_status(priv)) { void *rx_head;
dma_rx_size can be set as low as 64. Rx budget might be higher than that. Make sure to not overrun allocated rx buffers when budget is larger. Leave one descriptor unused to avoid wrap around of 'dirty_rx' vs 'cur_rx'. Signed-off-by: Baruch Siach <baruch@tkos.co.il> --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 1 + 1 file changed, 1 insertion(+)