diff mbox series

[net,2/2] net: stmmac: avoid rx queue overrun

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

Checks

Context Check Description
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for net
netdev/fixes_present success Fixes tag present in non-next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 1134 this patch: 1134
netdev/cc_maintainers warning 6 maintainers not CCed: linux-arm-kernel@lists.infradead.org edumazet@google.com pabeni@redhat.com kuba@kernel.org linux-stm32@st-md-mailman.stormreply.com mcoquelin.stm32@gmail.com
netdev/build_clang success Errors and warnings before: 1161 this patch: 1161
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 1161 this patch: 1161
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 7 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Baruch Siach Nov. 13, 2023, 5:42 p.m. UTC
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(+)

Comments

Jakub Kicinski Nov. 13, 2023, 10:52 p.m. UTC | #1
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?
Baruch Siach Nov. 14, 2023, 8:08 a.m. UTC | #2
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
Serge Semin Nov. 14, 2023, 4:04 p.m. UTC | #3
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
> 
>
Baruch Siach Nov. 14, 2023, 4:09 p.m. UTC | #4
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 mbox series

Patch

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;