@@ -99,6 +99,9 @@ static int hclge_devlink_reload_up(struct devlink *devlink,
static const struct devlink_ops hclge_devlink_ops = {
.info_get = hclge_devlink_info_get,
+};
+
+static const struct devlink_reload_ops hclge_devlink_reload_ops = {
.reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT),
.reload_down = hclge_devlink_reload_down,
.reload_up = hclge_devlink_reload_up,
@@ -119,6 +122,7 @@ int hclge_devlink_init(struct hclge_dev *hdev)
priv->hdev = hdev;
hdev->devlink = devlink;
+ devlink_set_reload_ops(devlink, &hclge_devlink_reload_ops);
devlink_register(devlink);
devlink_reload_enable(devlink);
return 0;
@@ -100,6 +100,9 @@ static int hclgevf_devlink_reload_up(struct devlink *devlink,
static const struct devlink_ops hclgevf_devlink_ops = {
.info_get = hclgevf_devlink_info_get,
+};
+
+static const struct devlink_reload_ops hclgevf_devlink_reload_ops = {
.reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT),
.reload_down = hclgevf_devlink_reload_down,
.reload_up = hclgevf_devlink_reload_up,
@@ -121,6 +124,7 @@ int hclgevf_devlink_init(struct hclgevf_dev *hdev)
priv->hdev = hdev;
hdev->devlink = devlink;
+ devlink_set_reload_ops(devlink, &hclgevf_devlink_reload_ops);
devlink_register(devlink);
devlink_reload_enable(devlink);
return 0;
@@ -3982,9 +3982,12 @@ static int mlx4_devlink_reload_up(struct devlink *devlink, enum devlink_reload_a
static const struct devlink_ops mlx4_devlink_ops = {
.port_type_set = mlx4_devlink_port_type_set,
+};
+
+static const struct devlink_reload_ops mlx4_devlink_reload_ops = {
.reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT),
- .reload_down = mlx4_devlink_reload_down,
- .reload_up = mlx4_devlink_reload_up,
+ .reload_down = mlx4_devlink_reload_down,
+ .reload_up = mlx4_devlink_reload_up,
};
static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -4025,6 +4028,7 @@ static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
goto err_params_unregister;
pci_save_state(pdev);
+ devlink_set_reload_ops(devlink, &mlx4_devlink_reload_ops);
devlink_register(devlink);
devlink_reload_enable(devlink);
return 0;
@@ -314,14 +314,17 @@ static const struct devlink_ops mlx5_devlink_ops = {
#endif
.flash_update = mlx5_devlink_flash_update,
.info_get = mlx5_devlink_info_get,
+ .trap_init = mlx5_devlink_trap_init,
+ .trap_fini = mlx5_devlink_trap_fini,
+ .trap_action_set = mlx5_devlink_trap_action_set,
+};
+
+static const struct devlink_reload_ops mlx5_devlink_reload_ops = {
.reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |
BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE),
.reload_limits = BIT(DEVLINK_RELOAD_LIMIT_NO_RESET),
.reload_down = mlx5_devlink_reload_down,
.reload_up = mlx5_devlink_reload_up,
- .trap_init = mlx5_devlink_trap_init,
- .trap_fini = mlx5_devlink_trap_fini,
- .trap_action_set = mlx5_devlink_trap_action_set,
};
void mlx5_devlink_trap_report(struct mlx5_core_dev *dev, int trap_id, struct sk_buff *skb,
@@ -813,6 +816,7 @@ int mlx5_devlink_register(struct devlink *devlink)
if (err)
goto traps_reg_err;
+ devlink_set_reload_ops(devlink, &mlx5_devlink_reload_ops);
return 0;
traps_reg_err:
@@ -1615,10 +1615,6 @@ mlxsw_devlink_trap_policer_counter_get(struct devlink *devlink,
}
static const struct devlink_ops mlxsw_devlink_ops = {
- .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |
- BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE),
- .reload_down = mlxsw_devlink_core_bus_device_reload_down,
- .reload_up = mlxsw_devlink_core_bus_device_reload_up,
.port_type_set = mlxsw_devlink_port_type_set,
.port_split = mlxsw_devlink_port_split,
.port_unsplit = mlxsw_devlink_port_unsplit,
@@ -1645,6 +1641,13 @@ static const struct devlink_ops mlxsw_devlink_ops = {
.trap_policer_counter_get = mlxsw_devlink_trap_policer_counter_get,
};
+static const struct devlink_reload_ops mlxsw_devlink_reload_ops = {
+ .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |
+ BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE),
+ .reload_down = mlxsw_devlink_core_bus_device_reload_down,
+ .reload_up = mlxsw_devlink_core_bus_device_reload_up,
+};
+
static int mlxsw_core_params_register(struct mlxsw_core *mlxsw_core)
{
int err;
@@ -2008,6 +2011,7 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
}
if (!reload) {
+ devlink_set_reload_ops(devlink, &mlxsw_devlink_reload_ops);
devlink_register(devlink);
devlink_reload_enable(devlink);
}
@@ -1246,9 +1246,6 @@ static const struct devlink_ops nsim_dev_devlink_ops = {
.eswitch_mode_get = nsim_devlink_eswitch_mode_get,
.supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT |
DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK,
- .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT),
- .reload_down = nsim_dev_reload_down,
- .reload_up = nsim_dev_reload_up,
.info_get = nsim_dev_info_get,
.flash_update = nsim_dev_flash_update,
.trap_init = nsim_dev_devlink_trap_init,
@@ -1267,6 +1264,12 @@ static const struct devlink_ops nsim_dev_devlink_ops = {
.trap_drop_counter_get = nsim_dev_devlink_trap_drop_counter_get,
};
+static const struct devlink_reload_ops nsim_dev_devlink_reload_ops = {
+ .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT),
+ .reload_down = nsim_dev_reload_down,
+ .reload_up = nsim_dev_reload_up,
+};
+
#define NSIM_DEV_MAX_MACS_DEFAULT 32
#define NSIM_DEV_TEST1_DEFAULT true
@@ -1511,6 +1514,7 @@ int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev)
goto err_psample_exit;
nsim_dev->esw_mode = DEVLINK_ESWITCH_MODE_LEGACY;
+ devlink_set_reload_ops(devlink, &nsim_dev_devlink_reload_ops);
devlink_register(devlink);
devlink_reload_enable(devlink);
return 0;
@@ -1193,15 +1193,6 @@ struct devlink_ops {
* implemementation.
*/
u32 supported_flash_update_params;
- unsigned long reload_actions;
- unsigned long reload_limits;
- int (*reload_down)(struct devlink *devlink, bool netns_change,
- enum devlink_reload_action action,
- enum devlink_reload_limit limit,
- struct netlink_ext_ack *extack);
- int (*reload_up)(struct devlink *devlink, enum devlink_reload_action action,
- enum devlink_reload_limit limit, u32 *actions_performed,
- struct netlink_ext_ack *extack);
int (*port_type_set)(struct devlink_port *devlink_port,
enum devlink_port_type port_type);
int (*port_split)(struct devlink *devlink, unsigned int port_index,
@@ -1482,6 +1473,20 @@ struct devlink_ops {
struct netlink_ext_ack *extack);
};
+struct devlink_reload_ops {
+ unsigned long reload_actions;
+ unsigned long reload_limits;
+ int (*reload_down)(struct devlink *devlink, bool netns_change,
+ enum devlink_reload_action action,
+ enum devlink_reload_limit limit,
+ struct netlink_ext_ack *extack);
+ int (*reload_up)(struct devlink *devlink,
+ enum devlink_reload_action action,
+ enum devlink_reload_limit limit,
+ u32 *actions_performed,
+ struct netlink_ext_ack *extack);
+};
+
void *devlink_priv(struct devlink *devlink);
struct devlink *priv_to_devlink(void *priv);
struct device *devlink_to_dev(const struct devlink *devlink);
@@ -1520,6 +1525,8 @@ static inline struct devlink *devlink_alloc(const struct devlink_ops *ops,
{
return devlink_alloc_ns(ops, priv_size, &init_net, dev);
}
+void devlink_set_reload_ops(struct devlink *devlink,
+ const struct devlink_reload_ops *ops);
void devlink_register(struct devlink *devlink);
void devlink_unregister(struct devlink *devlink);
void devlink_reload_enable(struct devlink *devlink);
@@ -54,6 +54,7 @@ struct devlink {
struct list_head trap_group_list;
struct list_head trap_policer_list;
const struct devlink_ops *ops;
+ const struct devlink_reload_ops *reload_ops;
struct xarray snapshot_ids;
struct devlink_dev_stats stats;
struct device *dev;
@@ -683,13 +684,15 @@ devlink_reload_combination_is_invalid(enum devlink_reload_action action,
static bool
devlink_reload_action_is_supported(struct devlink *devlink, enum devlink_reload_action action)
{
- return test_bit(action, &devlink->ops->reload_actions);
+ return devlink->reload_ops &&
+ test_bit(action, &devlink->reload_ops->reload_actions);
}
static bool
devlink_reload_limit_is_supported(struct devlink *devlink, enum devlink_reload_limit limit)
{
- return test_bit(limit, &devlink->ops->reload_limits);
+ return devlink->reload_ops &&
+ test_bit(limit, &devlink->reload_ops->reload_limits);
}
static int devlink_reload_stat_put(struct sk_buff *msg,
@@ -3954,9 +3957,9 @@ static void devlink_ns_change_notify(struct devlink *devlink,
devlink_notify(devlink, DEVLINK_CMD_DEL);
}
-static bool devlink_reload_supported(const struct devlink_ops *ops)
+static bool devlink_reload_supported(const struct devlink_reload_ops *ops)
{
- return ops->reload_down && ops->reload_up;
+ return ops && ops->reload_down && ops->reload_up;
}
static void devlink_reload_failed_set(struct devlink *devlink,
@@ -4042,14 +4045,16 @@ static int devlink_reload(struct devlink *devlink, struct net *dest_net,
curr_net = devlink_net(devlink);
devlink_ns_change_notify(devlink, dest_net, curr_net, false);
- err = devlink->ops->reload_down(devlink, !!dest_net, action, limit, extack);
+ err = devlink->reload_ops->reload_down(devlink, !!dest_net, action,
+ limit, extack);
if (err)
return err;
if (dest_net && !net_eq(dest_net, curr_net))
write_pnet(&devlink->_net, dest_net);
- err = devlink->ops->reload_up(devlink, action, limit, actions_performed, extack);
+ err = devlink->reload_ops->reload_up(devlink, action, limit,
+ actions_performed, extack);
devlink_reload_failed_set(devlink, !!err);
if (err)
return err;
@@ -4104,7 +4109,7 @@ static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info)
u32 actions_performed;
int err;
- if (!devlink_reload_supported(devlink->ops))
+ if (!devlink_reload_supported(devlink->reload_ops))
return -EOPNOTSUPP;
err = devlink_resources_validate(devlink, NULL, info);
@@ -8958,7 +8963,7 @@ static struct genl_family devlink_nl_family __ro_after_init = {
.n_mcgrps = ARRAY_SIZE(devlink_nl_mcgrps),
};
-static bool devlink_reload_actions_valid(const struct devlink_ops *ops)
+static bool devlink_reload_actions_valid(const struct devlink_reload_ops *ops)
{
const struct devlink_reload_combination *comb;
int i;
@@ -8987,6 +8992,25 @@ static bool devlink_reload_actions_valid(const struct devlink_ops *ops)
return true;
}
+/**
+ * devlink_set_reload_ops - Set devlink reload ops
+ *
+ * @devlink: devlink
+ * @ops: devlink reload ops to set
+ *
+ * This interface allows us to set reload ops separatelly from
+ * the devlink_alloc.
+ */
+void devlink_set_reload_ops(struct devlink *devlink,
+ const struct devlink_reload_ops *ops)
+{
+ WARN_ON(!devlink_reload_actions_valid(ops));
+ ASSERT_DEVLINK_NOT_REGISTERED(devlink);
+
+ devlink->reload_ops = ops;
+}
+EXPORT_SYMBOL_GPL(devlink_set_reload_ops);
+
/**
* devlink_alloc_ns - Allocate new devlink instance resources
* in specific namespace
@@ -9008,8 +9032,6 @@ struct devlink *devlink_alloc_ns(const struct devlink_ops *ops,
int ret;
WARN_ON(!ops || !dev);
- if (!devlink_reload_actions_valid(ops))
- return NULL;
devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL);
if (!devlink)
@@ -9157,7 +9179,7 @@ void devlink_unregister(struct devlink *devlink)
wait_for_completion(&devlink->comp);
mutex_lock(&devlink_mutex);
- WARN_ON(devlink_reload_supported(devlink->ops) &&
+ WARN_ON(devlink_reload_supported(devlink->reload_ops) &&
devlink->reload_enabled);
devlink_notify_unregister(devlink);
xa_clear_mark(&devlinks, devlink->index, DEVLINK_REGISTERED);
@@ -10315,7 +10337,7 @@ int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id,
{
struct devlink_param_item *param_item;
- if (!devlink_reload_supported(devlink->ops))
+ if (!devlink_reload_supported(devlink->reload_ops))
return -EOPNOTSUPP;
param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
@@ -11518,7 +11540,7 @@ static void __net_exit devlink_pernet_pre_exit(struct net *net)
if (!net_eq(devlink_net(devlink), net))
goto retry;
- WARN_ON(!devlink_reload_supported(devlink->ops));
+ WARN_ON(!devlink_reload_supported(devlink->reload_ops));
err = devlink_reload(devlink, &init_net,
DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
DEVLINK_RELOAD_LIMIT_UNSPEC,