Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net/mlx5: Add support for devlink reload limit no reset

Add support for devlink reload action fw_activate with reload limit
no_reset which does firmware live patching, updating the firmware image
without reset, no downtime and no configuration lose. The driver checks
if the firmware is capable of handling the pending firmware changes as a
live patch. If it is then it triggers firmware live patching flow.

Signed-off-by: Moshe Shemesh <moshe@mellanox.com>
Reviewed-by: Saeed Mahameed <saeedm@nvidia.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Moshe Shemesh and committed by
Jakub Kicinski
bef878e8 2d693567

+25
+25
drivers/net/ethernet/mellanox/mlx5/core/devlink.c
··· 111 111 return err; 112 112 } 113 113 114 + static int mlx5_devlink_trigger_fw_live_patch(struct devlink *devlink, 115 + struct netlink_ext_ack *extack) 116 + { 117 + struct mlx5_core_dev *dev = devlink_priv(devlink); 118 + u8 reset_level; 119 + int err; 120 + 121 + err = mlx5_fw_reset_query(dev, &reset_level, NULL); 122 + if (err) 123 + return err; 124 + if (!(reset_level & MLX5_MFRL_REG_RESET_LEVEL0)) { 125 + NL_SET_ERR_MSG_MOD(extack, 126 + "FW upgrade to the stored FW can't be done by FW live patching"); 127 + return -EINVAL; 128 + } 129 + 130 + return mlx5_fw_reset_set_live_patch(dev); 131 + } 132 + 114 133 static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change, 115 134 enum devlink_reload_action action, 116 135 enum devlink_reload_limit limit, ··· 142 123 mlx5_unload_one(dev, false); 143 124 return 0; 144 125 case DEVLINK_RELOAD_ACTION_FW_ACTIVATE: 126 + if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET) 127 + return mlx5_devlink_trigger_fw_live_patch(devlink, extack); 145 128 return mlx5_devlink_reload_fw_activate(devlink, extack); 146 129 default: 147 130 /* Unsupported action should not get to this function */ ··· 161 140 *actions_performed = BIT(action); 162 141 switch (action) { 163 142 case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: 143 + return mlx5_load_one(dev, false); 164 144 case DEVLINK_RELOAD_ACTION_FW_ACTIVATE: 145 + if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET) 146 + break; 165 147 /* On fw_activate action, also driver is reloaded and reinit performed */ 166 148 *actions_performed |= BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT); 167 149 return mlx5_load_one(dev, false); ··· 192 168 .info_get = mlx5_devlink_info_get, 193 169 .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) | 194 170 BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE), 171 + .reload_limits = BIT(DEVLINK_RELOAD_LIMIT_NO_RESET), 195 172 .reload_down = mlx5_devlink_reload_down, 196 173 .reload_up = mlx5_devlink_reload_up, 197 174 };