mlxsw: Fixes for PTP support
Subsystems (3)
Petr Machata
maintainercover mlxsw: Fixes for PTP support
This set fixes several issues in mlxsw PTP code.
- Patch #1 fixes compilation warnings.
- Patch #2 adjusts the order of operation during cleanup, thereby closing the window after PTP state was already cleaned in the ASIC for the given port, but before the port is removed, when the user could still in theory make changes to the configuration.
- Patch #3 protects the PTP configuration with a custom mutex, instead of relying on RTNL, which is not held in all access paths.
- Patch #4 forbids enablement of PTP only in RX or only in TX. The driver implicitly assumed this would be the case, but neglected to sanitize the configuration.
Amit Cohen (4):
mlxsw: spectrum_ptp: Fix compilation warnings
mlxsw: spectrum: Clear PTP configuration after unregistering the
netdevice
mlxsw: spectrum_ptp: Protect PTP configuration with a mutex
mlxsw: spectrum_ptp: Forbid PTP enablement only in RX or in TX
.../net/ethernet/mellanox/mlxsw/spectrum.c | 2 +- .../ethernet/mellanox/mlxsw/spectrum_ptp.c | 30 ++++++++++++++----- .../ethernet/mellanox/mlxsw/spectrum_ptp.h | 18 ++++++----- 3 files changed, 34 insertions(+), 16 deletions(-)
Signature · 1 line
2.35.3
Petr Machata
maintainerPATCH 1/4 mlxsw: spectrum_ptp: Fix compilation warnings
From: Amit Cohen <[email protected]>
In case that 'CONFIG_PTP_1588_CLOCK' is not enabled in the config file, there are implementations for the functions mlxsw_{sp,sp2}_ptp_txhdr_construct() as part of 'spectrum_ptp.h'. In this case, they should be defined as 'static' as they are not supposed to be used out of this file. Make the functions 'static', otherwise the following warnings are returned:
"warning: no previous prototype for 'mlxsw_sp_ptp_txhdr_construct'" "warning: no previous prototype for 'mlxsw_sp2_ptp_txhdr_construct'"
In addition, make the functions 'inline' for case that 'spectrum_ptp.h' will be included anywhere else and the functions would probably not be used, so compilation warnings about unused static will be returned.
--- .../net/ethernet/mellanox/mlxsw/spectrum_ptp.h | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-)
drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.h +10 -8
@@ -171,10 +171,11 @@ static inline void mlxsw_sp1_get_stats(struct mlxsw_sp_port *mlxsw_sp_port, { } -int mlxsw_sp_ptp_txhdr_construct (struct mlxsw_core *mlxsw_core, -struct mlxsw_sp_port *mlxsw_sp_port, -struct sk_buff *skb, -const struct mlxsw_tx_info *tx_info) +static inline int +mlxsw_sp_ptp_txhdr_construct (struct mlxsw_core *mlxsw_core, +struct mlxsw_sp_port *mlxsw_sp_port, +struct sk_buff *skb, +const struct mlxsw_tx_info *tx_info) {return -EOPNOTSUPP ; }
@@ -231,10 +232,11 @@ static inline int mlxsw_sp2_ptp_get_ts_info(struct mlxsw_sp *mlxsw_sp,return mlxsw_sp_ptp_get_ts_info_noptp (info); } -int mlxsw_sp2_ptp_txhdr_construct (struct mlxsw_core *mlxsw_core, -struct mlxsw_sp_port *mlxsw_sp_port, -struct sk_buff *skb, -const struct mlxsw_tx_info *tx_info) +static inline int +mlxsw_sp2_ptp_txhdr_construct (struct mlxsw_core *mlxsw_core, +struct mlxsw_sp_port *mlxsw_sp_port, +struct sk_buff *skb, +const struct mlxsw_tx_info *tx_info) {return -EOPNOTSUPP ; }
Signature · 1 line
2.35.3
Petr Machata
maintainerPATCH 2/4 mlxsw: spectrum: Clear PTP configuration after unregistering the netdevice
In reply to Petr MachataFrom: Amit Cohen <[email protected]>
Currently as part of removing port, PTP API is called to clear the existing configuration and set the 'rx_filter' and 'tx_type' to zero. The clearing is done before unregistering the netdevice, which means that there is a window of time in which the user can reconfigure PTP in the port, and this configuration will not be cleared.
Reorder the operations, clear PTP configuration after unregistering the netdevice.
--- drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlxsw/spectrum.c +1 -1
@@ -1897,9 +1897,9 @@ static void mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u16 local_port)cancel_delayed_work_sync (&mlxsw_sp_port->periodic_hw_stats.update_dw);cancel_delayed_work_sync (&mlxsw_sp_port->ptp.shaper_dw); -mlxsw_sp_port_ptp_clear (mlxsw_sp_port);mlxsw_core_port_clear (mlxsw_sp->core, local_port, mlxsw_sp);unregister_netdev (mlxsw_sp_port->dev);/* This calls ndo_stop */ +mlxsw_sp_port_ptp_clear (mlxsw_sp_port);mlxsw_sp_port_vlan_classification_set (mlxsw_sp_port, true, true); mlxsw_sp->ports[local_port] =NULL ;mlxsw_sp_port_vlan_flush (mlxsw_sp_port, true);
Signature · 1 line
2.35.3
Petr Machata
maintainerPATCH 3/4 mlxsw: spectrum_ptp: Protect PTP configuration with a mutex
In reply to Petr MachataFrom: Amit Cohen <[email protected]>
Currently the functions mlxsw_sp2_ptp_{configure, deconfigure}_port() assume that they are called when RTNL is locked and they warn otherwise.
The deconfigure function can be called when port is removed, for example as part of device reload, then there is no locked RTNL and the function warns [1].
To avoid such case, do not assume that RTNL protects this code, add a dedicated mutex instead. The mutex protects 'ptp_state->config' which stores the existing global configuration in hardware. Use this mutex also to protect the code which configures the hardware. Then, there will be only one configuration in any time, which will be updated in 'ptp_state' and a race will be avoided.
[1]:
RTNL: assertion failed at drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c (1600)
WARNING: CPU: 1 PID: 1583493 at drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c:1600 mlxsw_sp2_ptp_hwtstamp_set+0x2d3/0x300 [mlxsw_spectrum] [...] CPU: 1 PID: 1583493 Comm: devlink Not tainted5.19.0-rc8-custom-127022-gb371dffda095 #789 Hardware name: Mellanox Technologies Ltd.MSN3420/VMOD0005, BIOS 5.11 01/06/2019 RIP: 0010:mlxsw_sp2_ptp_hwtstamp_set+0x2d3/0x300[mlxsw_spectrum] [...] Call Trace: <TASK> mlxsw_sp_port_remove+0x7e/0x190 [mlxsw_spectrum] mlxsw_sp_fini+0xd1/0x270 [mlxsw_spectrum] mlxsw_core_bus_device_unregister+0x55/0x280 [mlxsw_core] mlxsw_devlink_core_bus_device_reload_down+0x1c/0x30[mlxsw_core] devlink_reload+0x1ee/0x230 devlink_nl_cmd_reload+0x4de/0x580 genl_family_rcv_msg_doit+0xdc/0x140 genl_rcv_msg+0xd7/0x1d0 netlink_rcv_skb+0x49/0xf0 genl_rcv+0x1f/0x30 netlink_unicast+0x22f/0x350 netlink_sendmsg+0x208/0x440 __sys_sendto+0xf0/0x140 __x64_sys_sendto+0x1b/0x20 do_syscall_64+0x35/0x80 entry_SYSCALL_64_after_hwframe+0x63/0xcd
--- .../ethernet/mellanox/mlxsw/spectrum_ptp.c | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-)
drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c +20 -7
@@ -46,6 +46,7 @@ struct mlxsw_sp2_ptp_state {* enabled. */ struct hwtstamp_config config; +struct mutex lock;/* Protects 'config' and HW configuration. */ };struct mlxsw_sp1_ptp_key {
@@ -1374,6 +1375,7 @@ struct mlxsw_sp_ptp_state *mlxsw_sp2_ptp_init(struct mlxsw_sp *mlxsw_sp) goto err_ptp_traps_set;refcount_set (&ptp_state->ptp_port_enabled_ref,0 ); +mutex_init (&ptp_state->lock);return &ptp_state->common; err_ptp_traps_set:
@@ -1388,6 +1390,7 @@ void mlxsw_sp2_ptp_fini(struct mlxsw_sp_ptp_state *ptp_state_common) ptp_state =mlxsw_sp2_ptp_state (mlxsw_sp); +mutex_destroy (&ptp_state->lock);mlxsw_sp_ptp_traps_unset (mlxsw_sp);kfree (ptp_state); }
@@ -1461,7 +1464,10 @@ int mlxsw_sp2_ptp_hwtstamp_get(struct mlxsw_sp_port *mlxsw_sp_port, ptp_state =mlxsw_sp2_ptp_state (mlxsw_sp_port->mlxsw_sp); +mutex_lock (&ptp_state->lock); *config = ptp_state->config; +mutex_unlock (&ptp_state->lock); +return 0 ; }
@@ -1574,8 +1580,6 @@ static int mlxsw_sp2_ptp_configure_port(struct mlxsw_sp_port *mlxsw_sp_port,struct mlxsw_sp2_ptp_state *ptp_state;int err; -ASSERT_RTNL (); - ptp_state =mlxsw_sp2_ptp_state (mlxsw_sp_port->mlxsw_sp);if (refcount_inc_not_zero (&ptp_state->ptp_port_enabled_ref))
@@ -1597,8 +1601,6 @@ static int mlxsw_sp2_ptp_deconfigure_port(struct mlxsw_sp_port *mlxsw_sp_port,struct mlxsw_sp2_ptp_state *ptp_state;int err; -ASSERT_RTNL (); - ptp_state =mlxsw_sp2_ptp_state (mlxsw_sp_port->mlxsw_sp);if (!refcount_dec_and_test (&ptp_state->ptp_port_enabled_ref))
@@ -1618,16 +1620,20 @@ static int mlxsw_sp2_ptp_deconfigure_port(struct mlxsw_sp_port *mlxsw_sp_port,int mlxsw_sp2_ptp_hwtstamp_set (struct mlxsw_sp_port *mlxsw_sp_port,struct hwtstamp_config *config) { +struct mlxsw_sp2_ptp_state *ptp_state;enum hwtstamp_rx_filters rx_filter;struct hwtstamp_config new_config;u16 new_ing_types, new_egr_types;bool ptp_enabled;int err; + ptp_state =mlxsw_sp2_ptp_state (mlxsw_sp_port->mlxsw_sp); +mutex_lock (&ptp_state->lock); + err =mlxsw_sp2_ptp_get_message_types (config, &new_ing_types, &new_egr_types, &rx_filter);if (err) -return err; + goto err_get_message_types; new_config.flags = config->flags; new_config.tx_type = config->tx_type;
@@ -1640,11 +1646,11 @@ int mlxsw_sp2_ptp_hwtstamp_set(struct mlxsw_sp_port *mlxsw_sp_port, err =mlxsw_sp2_ptp_configure_port (mlxsw_sp_port, new_ing_types, new_egr_types, new_config);if (err) -return err; + goto err_configure_port; }else if (!new_ing_types && !new_egr_types && ptp_enabled) { err =mlxsw_sp2_ptp_deconfigure_port (mlxsw_sp_port, new_config);if (err) -return err; + goto err_deconfigure_port; } mlxsw_sp_port->ptp.ing_types = new_ing_types;
@@ -1652,8 +1658,15 @@ int mlxsw_sp2_ptp_hwtstamp_set(struct mlxsw_sp_port *mlxsw_sp_port,/* Notify the ioctl caller what we are actually timestamping. */ config->rx_filter = rx_filter; +mutex_unlock (&ptp_state->lock);return 0 ; + +err_deconfigure_port: +err_configure_port: +err_get_message_types: +mutex_unlock (&ptp_state->lock); +return err; } int mlxsw_sp2_ptp_get_ts_info(struct mlxsw_sp *mlxsw_sp,
Signature · 1 line
2.35.3
Petr Machata
maintainerPATCH 4/4 mlxsw: spectrum_ptp: Forbid PTP enablement only in RX or in TX
In reply to Petr MachataFrom: Amit Cohen <[email protected]>
Currently mlxsw driver configures one global PTP configuration for all ports. The reason is that the switch behaves like a transparent clock between CPU port and front-panel ports. When time stamp is enabled in any port, the hardware is configured to update the correction field. The fact that the configuration of CPU port affects all the ports, makes the correction field update to be global for all ports. Otherwise, user will see odd values in the correction field, as the switch will update the correction field in the CPU port, but not in all the front-panel ports.
The CPU port is relevant in both RX and TX, so to avoid problematic configuration, forbid PTP enablement only in one direction, i.e., only in RX or TX.
Without the change:
$ hwstamp_ctl -i swp1 -r 12 -t 0 current settings: tx_type 0 rx_filter 0 new settings: tx_type 0 rx_filter 2 $ echo $? 0
With the change:
$ hwstamp_ctl -i swp1 -r 12 -t 0 current settings: tx_type 1 rx_filter 2 SIOCSHWTSTAMP failed: Invalid argument
--- drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c +3 -0
@@ -1529,6 +1529,9 @@ mlxsw_sp2_ptp_get_message_types(const struct hwtstamp_config *config,return -EINVAL ; } +if ((ing_types && !egr_types) || (!ing_types && egr_types)) +return -EINVAL ; + *p_ing_types = ing_types; *p_egr_types = egr_types;return 0 ;
Signature · 1 line
2.35.3
This series was applied to netdev/net.git (master) by David S. Miller <[email protected]>:
Hello:
This series was applied to netdev/net.git (master) by David S. Miller <[email protected]>:
Quoted 10 lines · On Fri, 12 Aug 2022 17:31:59 +0200 you wrote:
This set fixes several issues in mlxsw PTP code.
- Patch #1 fixes compilation warnings.
- Patch #2 adjusts the order of operation during cleanup, thereby closing the window after PTP state was already cleaned in the ASIC for the given port, but before the port is removed, when the user could still in theory make changes to the configuration.
[...]
Here is the summary with links:
- [net,1/4] mlxsw: spectrum_ptp: Fix compilation warnings
https://git.kernel.org/netdev/net/c/12e091389b29 - [net,2/4] mlxsw: spectrum: Clear PTP configuration after unregistering the netdevice https://git.kernel.org/netdev/net/c/a159e986ad26 - [net,3/4] mlxsw: spectrum_ptp: Protect PTP configuration with a mutex https://git.kernel.org/netdev/net/c/d72fdef21f07 - [net,4/4] mlxsw: spectrum_ptp: Forbid PTP enablement only in RX or in TX https://git.kernel.org/netdev/net/c/e01885c31bef
You are awesome, thank you!
Signature · 2 lines
Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html