diff mbox series

[net] net: dsa: felix: fix taprio guard band overflow at 10Mbps with jumbo frames

Message ID 20230613170907.2413559-1-vladimir.oltean@nxp.com (mailing list archive)
State Accepted
Commit 6ac7a27a8b07588497ed53dfd885df9c72bc67e0
Delegated to: Netdev Maintainers
Headers show
Series [net] net: dsa: felix: fix taprio guard band overflow at 10Mbps with jumbo frames | 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: 8 this patch: 8
netdev/cc_maintainers success CCed 11 of 11 maintainers
netdev/build_clang success Errors and warnings before: 8 this patch: 8
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 Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 8 this patch: 8
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 8 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Vladimir Oltean June 13, 2023, 5:09 p.m. UTC
The DEV_MAC_MAXLEN_CFG register contains a 16-bit value - up to 65535.
Plus 2 * VLAN_HLEN (4), that is up to 65543.

The picos_per_byte variable is the largest when "speed" is lowest -
SPEED_10 = 10. In that case it is (1000000L * 8) / 10 = 800000.

Their product - 52434400000 - exceeds 32 bits, which is a problem,
because apparently, a multiplication between two 32-bit factors is
evaluated as 32-bit before being assigned to a 64-bit variable.
In fact it's a problem for any MTU value larger than 5368.

Cast one of the factors of the multiplication to u64 to force the
multiplication to take place on 64 bits.

Issue found by Coverity.

Fixes: 55a515b1f5a9 ("net: dsa: felix: drop oversized frames with tc-taprio instead of hanging the port")
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 drivers/net/dsa/ocelot/felix_vsc9959.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Simon Horman June 14, 2023, 12:05 p.m. UTC | #1
On Tue, Jun 13, 2023 at 08:09:07PM +0300, Vladimir Oltean wrote:
> The DEV_MAC_MAXLEN_CFG register contains a 16-bit value - up to 65535.
> Plus 2 * VLAN_HLEN (4), that is up to 65543.
> 
> The picos_per_byte variable is the largest when "speed" is lowest -
> SPEED_10 = 10. In that case it is (1000000L * 8) / 10 = 800000.
> 
> Their product - 52434400000 - exceeds 32 bits, which is a problem,
> because apparently, a multiplication between two 32-bit factors is
> evaluated as 32-bit before being assigned to a 64-bit variable.
> In fact it's a problem for any MTU value larger than 5368.
> 
> Cast one of the factors of the multiplication to u64 to force the
> multiplication to take place on 64 bits.
> 
> Issue found by Coverity.
> 
> Fixes: 55a515b1f5a9 ("net: dsa: felix: drop oversized frames with tc-taprio instead of hanging the port")
> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>

Reviewed-by: Simon Horman <simon.horman@corigine.com>

In a similar vein, you may want to consider the following suggestion from
Coccinelle.

  .../felix_vsc9959.c:1382:2-8: WARNING: do_div() does a 64-by-32 division, please consider using div64_u64 instead.
Vladimir Oltean June 14, 2023, 12:17 p.m. UTC | #2
On Wed, Jun 14, 2023 at 02:05:15PM +0200, Simon Horman wrote:
> Reviewed-by: Simon Horman <simon.horman@corigine.com>

Thanks.

> In a similar vein, you may want to consider the following suggestion from
> Coccinelle.
> 
>   .../felix_vsc9959.c:1382:2-8: WARNING: do_div() does a 64-by-32 division, please consider using div64_u64 instead.
>

Yeah, but there, there's an earlier restriction for cycle_time to never
exceed NSEC_PER_SEC (1000000000L) which fits on 32 bits.

Nonetheless, it is a good reminder that there are too many disjoint
places in the kernel already that open-code the logic to advance a
taprio base time. It would indeed be good to consolidate all of those
into a static inline function offered by include/net/pkt_sched.h, which
is also warning-free.
Simon Horman June 14, 2023, 1:15 p.m. UTC | #3
On Wed, Jun 14, 2023 at 03:17:59PM +0300, Vladimir Oltean wrote:
> On Wed, Jun 14, 2023 at 02:05:15PM +0200, Simon Horman wrote:
> > Reviewed-by: Simon Horman <simon.horman@corigine.com>
> 
> Thanks.
> 
> > In a similar vein, you may want to consider the following suggestion from
> > Coccinelle.
> > 
> >   .../felix_vsc9959.c:1382:2-8: WARNING: do_div() does a 64-by-32 division, please consider using div64_u64 instead.
> >
> 
> Yeah, but there, there's an earlier restriction for cycle_time to never
> exceed NSEC_PER_SEC (1000000000L) which fits on 32 bits.

Thanks, understood.

> Nonetheless, it is a good reminder that there are too many disjoint
> places in the kernel already that open-code the logic to advance a
> taprio base time. It would indeed be good to consolidate all of those
> into a static inline function offered by include/net/pkt_sched.h, which
> is also warning-free.

Yes, that would be nice, now that you mention it.
patchwork-bot+netdevbpf@kernel.org June 15, 2023, 6:10 a.m. UTC | #4
Hello:

This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Tue, 13 Jun 2023 20:09:07 +0300 you wrote:
> The DEV_MAC_MAXLEN_CFG register contains a 16-bit value - up to 65535.
> Plus 2 * VLAN_HLEN (4), that is up to 65543.
> 
> The picos_per_byte variable is the largest when "speed" is lowest -
> SPEED_10 = 10. In that case it is (1000000L * 8) / 10 = 800000.
> 
> Their product - 52434400000 - exceeds 32 bits, which is a problem,
> because apparently, a multiplication between two 32-bit factors is
> evaluated as 32-bit before being assigned to a 64-bit variable.
> In fact it's a problem for any MTU value larger than 5368.
> 
> [...]

Here is the summary with links:
  - [net] net: dsa: felix: fix taprio guard band overflow at 10Mbps with jumbo frames
    https://git.kernel.org/netdev/net/c/6ac7a27a8b07

You are awesome, thank you!
diff mbox series

Patch

diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c
index 903532ea9fa4..bb39fedd46c7 100644
--- a/drivers/net/dsa/ocelot/felix_vsc9959.c
+++ b/drivers/net/dsa/ocelot/felix_vsc9959.c
@@ -1251,7 +1251,7 @@  static void vsc9959_tas_guard_bands_update(struct ocelot *ocelot, int port)
 	/* Consider the standard Ethernet overhead of 8 octets preamble+SFD,
 	 * 4 octets FCS, 12 octets IFG.
 	 */
-	needed_bit_time_ps = (maxlen + 24) * picos_per_byte;
+	needed_bit_time_ps = (u64)(maxlen + 24) * picos_per_byte;
 
 	dev_dbg(ocelot->dev,
 		"port %d: max frame size %d needs %llu ps at speed %d\n",