Skip to content

Commit ccdf072

Browse files
Moshe Shemeshkuba-moo
authored andcommitted
devlink: Add reload action option to devlink reload command
Add devlink reload action to allow the user to request a specific reload action. The action parameter is optional, if not specified then devlink driver re-init action is used (backward compatible). Note that when required to do firmware activation some drivers may need to reload the driver. On the other hand some drivers may need to reset the firmware to reinitialize the driver entities. Therefore, the devlink reload command returns the actions which were actually performed. Reload actions supported are: driver_reinit: driver entities re-initialization, applying devlink-param and devlink-resource values. fw_activate: firmware activate. command examples: $devlink dev reload pci/0000:82:00.0 action driver_reinit reload_actions_performed: driver_reinit $devlink dev reload pci/0000:82:00.0 action fw_activate reload_actions_performed: driver_reinit fw_activate Signed-off-by: Moshe Shemesh <[email protected]> Reviewed-by: Jakub Kicinski <[email protected]> Reviewed-by: Jacob Keller <[email protected]> Reviewed-by: Jiri Pirko <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 69d56e0 commit ccdf072

File tree

7 files changed

+131
-19
lines changed

7 files changed

+131
-19
lines changed

drivers/net/ethernet/mellanox/mlx4/main.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3946,6 +3946,7 @@ static int mlx4_restart_one_up(struct pci_dev *pdev, bool reload,
39463946
struct devlink *devlink);
39473947

39483948
static int mlx4_devlink_reload_down(struct devlink *devlink, bool netns_change,
3949+
enum devlink_reload_action action,
39493950
struct netlink_ext_ack *extack)
39503951
{
39513952
struct mlx4_priv *priv = devlink_priv(devlink);
@@ -3962,14 +3963,15 @@ static int mlx4_devlink_reload_down(struct devlink *devlink, bool netns_change,
39623963
return 0;
39633964
}
39643965

3965-
static int mlx4_devlink_reload_up(struct devlink *devlink,
3966-
struct netlink_ext_ack *extack)
3966+
static int mlx4_devlink_reload_up(struct devlink *devlink, enum devlink_reload_action action,
3967+
u32 *actions_performed, struct netlink_ext_ack *extack)
39673968
{
39683969
struct mlx4_priv *priv = devlink_priv(devlink);
39693970
struct mlx4_dev *dev = &priv->dev;
39703971
struct mlx4_dev_persistent *persist = dev->persist;
39713972
int err;
39723973

3974+
*actions_performed = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
39733975
err = mlx4_restart_one_up(persist->pdev, true, devlink);
39743976
if (err)
39753977
mlx4_err(persist->dev, "mlx4_restart_one_up failed, ret=%d\n",
@@ -3980,6 +3982,7 @@ static int mlx4_devlink_reload_up(struct devlink *devlink,
39803982

39813983
static const struct devlink_ops mlx4_devlink_ops = {
39823984
.port_type_set = mlx4_devlink_port_type_set,
3985+
.reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT),
39833986
.reload_down = mlx4_devlink_reload_down,
39843987
.reload_up = mlx4_devlink_reload_up,
39853988
};

drivers/net/ethernet/mellanox/mlx5/core/devlink.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ mlx5_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req,
8585
}
8686

8787
static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change,
88+
enum devlink_reload_action action,
8889
struct netlink_ext_ack *extack)
8990
{
9091
struct mlx5_core_dev *dev = devlink_priv(devlink);
@@ -93,11 +94,12 @@ static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change,
9394
return 0;
9495
}
9596

96-
static int mlx5_devlink_reload_up(struct devlink *devlink,
97-
struct netlink_ext_ack *extack)
97+
static int mlx5_devlink_reload_up(struct devlink *devlink, enum devlink_reload_action action,
98+
u32 *actions_performed, struct netlink_ext_ack *extack)
9899
{
99100
struct mlx5_core_dev *dev = devlink_priv(devlink);
100101

102+
*actions_performed = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
101103
return mlx5_load_one(dev, false);
102104
}
103105

@@ -114,6 +116,7 @@ static const struct devlink_ops mlx5_devlink_ops = {
114116
#endif
115117
.flash_update = mlx5_devlink_flash_update,
116118
.info_get = mlx5_devlink_info_get,
119+
.reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT),
117120
.reload_down = mlx5_devlink_reload_down,
118121
.reload_up = mlx5_devlink_reload_up,
119122
};

drivers/net/ethernet/mellanox/mlxsw/core.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1414,7 +1414,7 @@ mlxsw_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req,
14141414

14151415
static int
14161416
mlxsw_devlink_core_bus_device_reload_down(struct devlink *devlink,
1417-
bool netns_change,
1417+
bool netns_change, enum devlink_reload_action action,
14181418
struct netlink_ext_ack *extack)
14191419
{
14201420
struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
@@ -1427,11 +1427,13 @@ mlxsw_devlink_core_bus_device_reload_down(struct devlink *devlink,
14271427
}
14281428

14291429
static int
1430-
mlxsw_devlink_core_bus_device_reload_up(struct devlink *devlink,
1431-
struct netlink_ext_ack *extack)
1430+
mlxsw_devlink_core_bus_device_reload_up(struct devlink *devlink, enum devlink_reload_action action,
1431+
u32 *actions_performed, struct netlink_ext_ack *extack)
14321432
{
14331433
struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
14341434

1435+
*actions_performed = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |
1436+
BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE);
14351437
return mlxsw_core_bus_device_register(mlxsw_core->bus_info,
14361438
mlxsw_core->bus,
14371439
mlxsw_core->bus_priv, true,
@@ -1564,6 +1566,8 @@ mlxsw_devlink_trap_policer_counter_get(struct devlink *devlink,
15641566
}
15651567

15661568
static const struct devlink_ops mlxsw_devlink_ops = {
1569+
.reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |
1570+
BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE),
15671571
.reload_down = mlxsw_devlink_core_bus_device_reload_down,
15681572
.reload_up = mlxsw_devlink_core_bus_device_reload_up,
15691573
.port_type_set = mlxsw_devlink_port_type_set,

drivers/net/netdevsim/dev.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -701,7 +701,7 @@ static int nsim_dev_reload_create(struct nsim_dev *nsim_dev,
701701
static void nsim_dev_reload_destroy(struct nsim_dev *nsim_dev);
702702

703703
static int nsim_dev_reload_down(struct devlink *devlink, bool netns_change,
704-
struct netlink_ext_ack *extack)
704+
enum devlink_reload_action action, struct netlink_ext_ack *extack)
705705
{
706706
struct nsim_dev *nsim_dev = devlink_priv(devlink);
707707

@@ -717,8 +717,8 @@ static int nsim_dev_reload_down(struct devlink *devlink, bool netns_change,
717717
return 0;
718718
}
719719

720-
static int nsim_dev_reload_up(struct devlink *devlink,
721-
struct netlink_ext_ack *extack)
720+
static int nsim_dev_reload_up(struct devlink *devlink, enum devlink_reload_action action,
721+
u32 *actions_performed, struct netlink_ext_ack *extack)
722722
{
723723
struct nsim_dev *nsim_dev = devlink_priv(devlink);
724724

@@ -730,6 +730,7 @@ static int nsim_dev_reload_up(struct devlink *devlink,
730730
return -EINVAL;
731731
}
732732

733+
*actions_performed = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
733734
return nsim_dev_reload_create(nsim_dev, extack);
734735
}
735736

@@ -886,6 +887,7 @@ nsim_dev_devlink_trap_policer_counter_get(struct devlink *devlink,
886887
static const struct devlink_ops nsim_dev_devlink_ops = {
887888
.supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT |
888889
DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK,
890+
.reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT),
889891
.reload_down = nsim_dev_reload_down,
890892
.reload_up = nsim_dev_reload_up,
891893
.info_get = nsim_dev_info_get,

include/net/devlink.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,10 +1150,11 @@ struct devlink_ops {
11501150
* implemementation.
11511151
*/
11521152
u32 supported_flash_update_params;
1153+
unsigned long reload_actions;
11531154
int (*reload_down)(struct devlink *devlink, bool netns_change,
1154-
struct netlink_ext_ack *extack);
1155-
int (*reload_up)(struct devlink *devlink,
1156-
struct netlink_ext_ack *extack);
1155+
enum devlink_reload_action action, struct netlink_ext_ack *extack);
1156+
int (*reload_up)(struct devlink *devlink, enum devlink_reload_action action,
1157+
u32 *actions_performed, struct netlink_ext_ack *extack);
11571158
int (*port_type_set)(struct devlink_port *devlink_port,
11581159
enum devlink_port_type port_type);
11591160
int (*port_split)(struct devlink *devlink, unsigned int port_index,

include/uapi/linux/devlink.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,16 @@ enum {
301301
DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE,
302302
};
303303

304+
enum devlink_reload_action {
305+
DEVLINK_RELOAD_ACTION_UNSPEC,
306+
DEVLINK_RELOAD_ACTION_DRIVER_REINIT, /* Driver entities re-instantiation */
307+
DEVLINK_RELOAD_ACTION_FW_ACTIVATE, /* FW activate */
308+
309+
/* Add new reload actions above */
310+
__DEVLINK_RELOAD_ACTION_MAX,
311+
DEVLINK_RELOAD_ACTION_MAX = __DEVLINK_RELOAD_ACTION_MAX - 1
312+
};
313+
304314
enum devlink_attr {
305315
/* don't change the order or add anything between, this is ABI! */
306316
DEVLINK_ATTR_UNSPEC,
@@ -493,6 +503,9 @@ enum devlink_attr {
493503
DEVLINK_ATTR_FLASH_UPDATE_STATUS_TIMEOUT, /* u64 */
494504
DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK, /* bitfield32 */
495505

506+
DEVLINK_ATTR_RELOAD_ACTION, /* u8 */
507+
DEVLINK_ATTR_RELOAD_ACTIONS_PERFORMED, /* bitfield32 */
508+
496509
/* add new attributes above here, update the policy in devlink.c */
497510

498511
__DEVLINK_ATTR_MAX,

net/core/devlink.c

Lines changed: 92 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,12 @@ static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
479479
return 0;
480480
}
481481

482+
static bool
483+
devlink_reload_action_is_supported(struct devlink *devlink, enum devlink_reload_action action)
484+
{
485+
return test_bit(action, &devlink->ops->reload_actions);
486+
}
487+
482488
static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
483489
enum devlink_command cmd, u32 portid,
484490
u32 seq, int flags)
@@ -2984,29 +2990,68 @@ bool devlink_is_reload_failed(const struct devlink *devlink)
29842990
EXPORT_SYMBOL_GPL(devlink_is_reload_failed);
29852991

29862992
static int devlink_reload(struct devlink *devlink, struct net *dest_net,
2993+
enum devlink_reload_action action, u32 *actions_performed,
29872994
struct netlink_ext_ack *extack)
29882995
{
29892996
int err;
29902997

29912998
if (!devlink->reload_enabled)
29922999
return -EOPNOTSUPP;
29933000

2994-
err = devlink->ops->reload_down(devlink, !!dest_net, extack);
3001+
err = devlink->ops->reload_down(devlink, !!dest_net, action, extack);
29953002
if (err)
29963003
return err;
29973004

29983005
if (dest_net && !net_eq(dest_net, devlink_net(devlink)))
29993006
devlink_reload_netns_change(devlink, dest_net);
30003007

3001-
err = devlink->ops->reload_up(devlink, extack);
3008+
err = devlink->ops->reload_up(devlink, action, actions_performed, extack);
30023009
devlink_reload_failed_set(devlink, !!err);
3003-
return err;
3010+
if (err)
3011+
return err;
3012+
3013+
WARN_ON(!(*actions_performed & BIT(action)));
3014+
return 0;
3015+
}
3016+
3017+
static int
3018+
devlink_nl_reload_actions_performed_snd(struct devlink *devlink, u32 actions_performed,
3019+
enum devlink_command cmd, struct genl_info *info)
3020+
{
3021+
struct sk_buff *msg;
3022+
void *hdr;
3023+
3024+
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3025+
if (!msg)
3026+
return -ENOMEM;
3027+
3028+
hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq, &devlink_nl_family, 0, cmd);
3029+
if (!hdr)
3030+
goto free_msg;
3031+
3032+
if (devlink_nl_put_handle(msg, devlink))
3033+
goto nla_put_failure;
3034+
3035+
if (nla_put_bitfield32(msg, DEVLINK_ATTR_RELOAD_ACTIONS_PERFORMED, actions_performed,
3036+
actions_performed))
3037+
goto nla_put_failure;
3038+
genlmsg_end(msg, hdr);
3039+
3040+
return genlmsg_reply(msg, info);
3041+
3042+
nla_put_failure:
3043+
genlmsg_cancel(msg, hdr);
3044+
free_msg:
3045+
nlmsg_free(msg);
3046+
return -EMSGSIZE;
30043047
}
30053048

30063049
static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info)
30073050
{
30083051
struct devlink *devlink = info->user_ptr[0];
3052+
enum devlink_reload_action action;
30093053
struct net *dest_net = NULL;
3054+
u32 actions_performed;
30103055
int err;
30113056

30123057
if (!devlink_reload_supported(devlink->ops))
@@ -3026,12 +3071,30 @@ static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info)
30263071
return PTR_ERR(dest_net);
30273072
}
30283073

3029-
err = devlink_reload(devlink, dest_net, info->extack);
3074+
if (info->attrs[DEVLINK_ATTR_RELOAD_ACTION])
3075+
action = nla_get_u8(info->attrs[DEVLINK_ATTR_RELOAD_ACTION]);
3076+
else
3077+
action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT;
3078+
3079+
if (!devlink_reload_action_is_supported(devlink, action)) {
3080+
NL_SET_ERR_MSG_MOD(info->extack,
3081+
"Requested reload action is not supported by the driver");
3082+
return -EOPNOTSUPP;
3083+
}
3084+
3085+
err = devlink_reload(devlink, dest_net, action, &actions_performed, info->extack);
30303086

30313087
if (dest_net)
30323088
put_net(dest_net);
30333089

3034-
return err;
3090+
if (err)
3091+
return err;
3092+
/* For backward compatibility generate reply only if attributes used by user */
3093+
if (!info->attrs[DEVLINK_ATTR_RELOAD_ACTION])
3094+
return 0;
3095+
3096+
return devlink_nl_reload_actions_performed_snd(devlink, actions_performed,
3097+
DEVLINK_CMD_RELOAD, info);
30353098
}
30363099

30373100
static int devlink_nl_flash_update_fill(struct sk_buff *msg,
@@ -7282,6 +7345,8 @@ static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
72827345
[DEVLINK_ATTR_TRAP_POLICER_RATE] = { .type = NLA_U64 },
72837346
[DEVLINK_ATTR_TRAP_POLICER_BURST] = { .type = NLA_U64 },
72847347
[DEVLINK_ATTR_PORT_FUNCTION] = { .type = NLA_NESTED },
7348+
[DEVLINK_ATTR_RELOAD_ACTION] = NLA_POLICY_RANGE(NLA_U8, DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
7349+
DEVLINK_RELOAD_ACTION_MAX),
72857350
};
72867351

72877352
static const struct genl_small_ops devlink_nl_ops[] = {
@@ -7615,6 +7680,21 @@ static struct genl_family devlink_nl_family __ro_after_init = {
76157680
.n_mcgrps = ARRAY_SIZE(devlink_nl_mcgrps),
76167681
};
76177682

7683+
static bool devlink_reload_actions_valid(const struct devlink_ops *ops)
7684+
{
7685+
if (!devlink_reload_supported(ops)) {
7686+
if (WARN_ON(ops->reload_actions))
7687+
return false;
7688+
return true;
7689+
}
7690+
7691+
if (WARN_ON(!ops->reload_actions ||
7692+
ops->reload_actions & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) ||
7693+
ops->reload_actions >= BIT(__DEVLINK_RELOAD_ACTION_MAX)))
7694+
return false;
7695+
return true;
7696+
}
7697+
76187698
/**
76197699
* devlink_alloc - Allocate new devlink instance resources
76207700
*
@@ -7631,6 +7711,9 @@ struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size)
76317711
if (WARN_ON(!ops))
76327712
return NULL;
76337713

7714+
if (!devlink_reload_actions_valid(ops))
7715+
return NULL;
7716+
76347717
devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL);
76357718
if (!devlink)
76367719
return NULL;
@@ -9960,6 +10043,7 @@ int devlink_compat_switch_id_get(struct net_device *dev,
996010043
static void __net_exit devlink_pernet_pre_exit(struct net *net)
996110044
{
996210045
struct devlink *devlink;
10046+
u32 actions_performed;
996310047
int err;
996410048

996510049
/* In case network namespace is getting destroyed, reload
@@ -9970,7 +10054,9 @@ static void __net_exit devlink_pernet_pre_exit(struct net *net)
997010054
if (net_eq(devlink_net(devlink), net)) {
997110055
if (WARN_ON(!devlink_reload_supported(devlink->ops)))
997210056
continue;
9973-
err = devlink_reload(devlink, &init_net, NULL);
10057+
err = devlink_reload(devlink, &init_net,
10058+
DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
10059+
&actions_performed, NULL);
997410060
if (err && err != -EOPNOTSUPP)
997510061
pr_warn("Failed to reload devlink instance into init_net\n");
997610062
}

0 commit comments

Comments
 (0)