History

devlink: Add devlink reload limit option

Add reload limit to demand restrictions on reload actions. Reload limits supported: no_reset: No reset allowed, no down time allowed, no link flap and no configuration is lost. By default reload limit is unspecified and so no constraints on reload actions are required. Some combinations of action and limit are invalid. For example, driver can not reinitialize its entities without any downtime. The no_reset reload limit will have usecase in this patchset to implement restricted fw_activate on mlx5. Have the uapi parameter of reload limit ready for future support of multiselection.

Moshe Shemesh committed 6 years ago

Commit dc64cc71 parent ccdf0727 files · +119 −13Browse files

Unified · Split

7 files
  1. drivers/net/ethernet/mellanox/mlx4/main.c +3 −1
  2. drivers/net/ethernet/mellanox/mlx5/core/devlink.c +3 −1
  3. drivers/net/ethernet/mellanox/mlxsw/core.c +3 −1
  4. drivers/net/netdevsim/dev.c +4 −2
  5. include/net/devlink.h +6 −2
  6. include/uapi/linux/devlink.h +14 −0
  7. net/core/devlink.c +86 −6
drivers/net/ethernet/mellanox/mlx4/main.c+3−1
@@ -3947,6 +3947,7 @@ static int mlx4_restart_one_up(struct pci_dev *pdev, bool reload, · 3946 unmodified lines
39473947
39483948 static int mlx4_devlink_reload_down(struct devlink *devlink, bool netns_change,
39493949 enum devlink_reload_action action,
3950+ enum devlink_reload_limit limit,
39503951 struct netlink_ext_ack *extack)
39513952 {
39523953 struct mlx4_priv *priv = devlink_priv(devlink);
@@ -3964,7 +3965,8 @@ static int mlx4_devlink_reload_down(struct devlink *devlink, bool netns_change, · 11 unmodified lines
39643965 }
39653966
39663967 static int mlx4_devlink_reload_up(struct devlink *devlink, enum devlink_reload_action action,
3967− u32 *actions_performed, struct netlink_ext_ack *extack)
3968+ enum devlink_reload_limit limit, u32 *actions_performed,
3969+ struct netlink_ext_ack *extack)
39683970 {
39693971 struct mlx4_priv *priv = devlink_priv(devlink);
39703972 struct mlx4_dev *dev = &priv->dev;
drivers/net/ethernet/mellanox/mlx5/core/devlink.c+3−1
@@ -86,6 +86,7 @@ mlx5_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req, · 85 unmodified lines
8686
8787 static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change,
8888 enum devlink_reload_action action,
89+ enum devlink_reload_limit limit,
8990 struct netlink_ext_ack *extack)
9091 {
9192 struct mlx5_core_dev *dev = devlink_priv(devlink);
@@ -95,7 +96,8 @@ static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change, · 3 unmodified lines
9596 }
9697
9798 static int mlx5_devlink_reload_up(struct devlink *devlink, enum devlink_reload_action action,
98− u32 *actions_performed, struct netlink_ext_ack *extack)
99+ enum devlink_reload_limit limit, u32 *actions_performed,
100+ struct netlink_ext_ack *extack)
99101 {
100102 struct mlx5_core_dev *dev = devlink_priv(devlink);
101103
drivers/net/ethernet/mellanox/mlxsw/core.c+3−1
@@ -1415,6 +1415,7 @@ mlxsw_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req, · 1414 unmodified lines
14151415 static int
14161416 mlxsw_devlink_core_bus_device_reload_down(struct devlink *devlink,
14171417 bool netns_change, enum devlink_reload_action action,
1418+ enum devlink_reload_limit limit,
14181419 struct netlink_ext_ack *extack)
14191420 {
14201421 struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
@@ -1428,7 +1429,8 @@ mlxsw_devlink_core_bus_device_reload_down(struct devlink *devlink, · 7 unmodified lines
14281429
14291430 static int
14301431 mlxsw_devlink_core_bus_device_reload_up(struct devlink *devlink, enum devlink_reload_action action,
1431− u32 *actions_performed, struct netlink_ext_ack *extack)
1432+ enum devlink_reload_limit limit, u32 *actions_performed,
1433+ struct netlink_ext_ack *extack)
14321434 {
14331435 struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
14341436
drivers/net/netdevsim/dev.c+4−2
@@ -701,7 +701,8 @@ static int nsim_dev_reload_create(struct nsim_dev *nsim_dev, · 700 unmodified lines
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− enum devlink_reload_action action, struct netlink_ext_ack *extack)
704+ enum devlink_reload_action action, enum devlink_reload_limit limit,
705+ struct netlink_ext_ack *extack)
705706 {
706707 struct nsim_dev *nsim_dev = devlink_priv(devlink);
707708
@@ -718,7 +719,8 @@ static int nsim_dev_reload_down(struct devlink *devlink, bool netns_change, · 10 unmodified lines
718719 }
719720
720721 static int nsim_dev_reload_up(struct devlink *devlink, enum devlink_reload_action action,
721− u32 *actions_performed, struct netlink_ext_ack *extack)
722+ enum devlink_reload_limit limit, u32 *actions_performed,
723+ struct netlink_ext_ack *extack)
722724 {
723725 struct nsim_dev *nsim_dev = devlink_priv(devlink);
724726
include/net/devlink.h+6−2
@@ -1151,10 +1151,14 @@ struct devlink_ops { · 1150 unmodified lines
11511151 */
11521152 u32 supported_flash_update_params;
11531153 unsigned long reload_actions;
1154+ unsigned long reload_limits;
11541155 int (*reload_down)(struct devlink *devlink, bool netns_change,
1155− enum devlink_reload_action action, struct netlink_ext_ack *extack);
1156+ enum devlink_reload_action action,
1157+ enum devlink_reload_limit limit,
1158+ struct netlink_ext_ack *extack);
11561159 int (*reload_up)(struct devlink *devlink, enum devlink_reload_action action,
1157− u32 *actions_performed, struct netlink_ext_ack *extack);
1160+ enum devlink_reload_limit limit, u32 *actions_performed,
1161+ struct netlink_ext_ack *extack);
11581162 int (*port_type_set)(struct devlink_port *devlink_port,
11591163 enum devlink_port_type port_type);
11601164 int (*port_split)(struct devlink *devlink, unsigned int port_index,
include/uapi/linux/devlink.h+14−0
@@ -311,6 +311,19 @@ enum devlink_reload_action { · 310 unmodified lines
311311 DEVLINK_RELOAD_ACTION_MAX = __DEVLINK_RELOAD_ACTION_MAX - 1
312312 };
313313
314+enum devlink_reload_limit {
315+ DEVLINK_RELOAD_LIMIT_UNSPEC, /* unspecified, no constraints */
316+ DEVLINK_RELOAD_LIMIT_NO_RESET, /* No reset allowed, no down time allowed,
317+ * no link flap and no configuration is lost.
318+ */
319+
320+ /* Add new reload limit above */
321+ __DEVLINK_RELOAD_LIMIT_MAX,
322+ DEVLINK_RELOAD_LIMIT_MAX = __DEVLINK_RELOAD_LIMIT_MAX - 1
323+};
324+
325+#define DEVLINK_RELOAD_LIMITS_VALID_MASK (BIT(__DEVLINK_RELOAD_LIMIT_MAX) - 1)
326+
314327 enum devlink_attr {
315328 /* don't change the order or add anything between, this is ABI! */
316329 DEVLINK_ATTR_UNSPEC,
@@ -505,6 +518,7 @@ enum devlink_attr { · 188 unmodified lines
505518
506519 DEVLINK_ATTR_RELOAD_ACTION, /* u8 */
507520 DEVLINK_ATTR_RELOAD_ACTIONS_PERFORMED, /* bitfield32 */
521+ DEVLINK_ATTR_RELOAD_LIMITS, /* bitfield32 */
508522
509523 /* add new attributes above here, update the policy in devlink.c */
510524
net/core/devlink.c+86−6
@@ -479,12 +479,44 @@ static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink) · 478 unmodified lines
479479 return 0;
480480 }
481481
482+struct devlink_reload_combination {
483+ enum devlink_reload_action action;
484+ enum devlink_reload_limit limit;
485+};
486+
487+static const struct devlink_reload_combination devlink_reload_invalid_combinations[] = {
488+ {
489+ /* can't reinitialize driver with no down time */
490+ .action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
491+ .limit = DEVLINK_RELOAD_LIMIT_NO_RESET,
492+ },
493+};
494+
495+static bool
496+devlink_reload_combination_is_invalid(enum devlink_reload_action action,
497+ enum devlink_reload_limit limit)
498+{
499+ int i;
500+
501+ for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++)
502+ if (devlink_reload_invalid_combinations[i].action == action &&
503+ devlink_reload_invalid_combinations[i].limit == limit)
504+ return true;
505+ return false;
506+}
507+
482508 static bool
483509 devlink_reload_action_is_supported(struct devlink *devlink, enum devlink_reload_action action)
484510 {
485511 return test_bit(action, &devlink->ops->reload_actions);
486512 }
487513
514+static bool
515+devlink_reload_limit_is_supported(struct devlink *devlink, enum devlink_reload_limit limit)
516+{
517+ return test_bit(limit, &devlink->ops->reload_limits);
518+}
519+
488520 static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
489521 enum devlink_command cmd, u32 portid,
490522 u32 seq, int flags)
@@ -2990,22 +3022,22 @@ bool devlink_is_reload_failed(const struct devlink *devlink) · 2499 unmodified lines
29903022 EXPORT_SYMBOL_GPL(devlink_is_reload_failed);
29913023
29923024 static int devlink_reload(struct devlink *devlink, struct net *dest_net,
2993− enum devlink_reload_action action, u32 *actions_performed,
2994− struct netlink_ext_ack *extack)
3025+ enum devlink_reload_action action, enum devlink_reload_limit limit,
3026+ u32 *actions_performed, struct netlink_ext_ack *extack)
29953027 {
29963028 int err;
29973029
29983030 if (!devlink->reload_enabled)
29993031 return -EOPNOTSUPP;
30003032
3001− err = devlink->ops->reload_down(devlink, !!dest_net, action, extack);
3033+ err = devlink->ops->reload_down(devlink, !!dest_net, action, limit, extack);
30023034 if (err)
30033035 return err;
30043036
30053037 if (dest_net && !net_eq(dest_net, devlink_net(devlink)))
30063038 devlink_reload_netns_change(devlink, dest_net);
30073039
3008− err = devlink->ops->reload_up(devlink, action, actions_performed, extack);
3040+ err = devlink->ops->reload_up(devlink, action, limit, actions_performed, extack);
30093041 devlink_reload_failed_set(devlink, !!err);
30103042 if (err)
30113043 return err;
@@ -3050,6 +3082,7 @@ static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info) · 38 unmodified lines
30503082 {
30513083 struct devlink *devlink = info->user_ptr[0];
30523084 enum devlink_reload_action action;
3085+ enum devlink_reload_limit limit;
30533086 struct net *dest_net = NULL;
30543087 u32 actions_performed;
30553088 int err;
@@ -3082,7 +3115,38 @@ static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info) · 26 unmodified lines
30823115 return -EOPNOTSUPP;
30833116 }
30843117
3085− err = devlink_reload(devlink, dest_net, action, &actions_performed, info->extack);
3118+ limit = DEVLINK_RELOAD_LIMIT_UNSPEC;
3119+ if (info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]) {
3120+ struct nla_bitfield32 limits;
3121+ u32 limits_selected;
3122+
3123+ limits = nla_get_bitfield32(info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]);
3124+ limits_selected = limits.value & limits.selector;
3125+ if (!limits_selected) {
3126+ NL_SET_ERR_MSG_MOD(info->extack, "Invalid limit selected");
3127+ return -EINVAL;
3128+ }
3129+ for (limit = 0 ; limit <= DEVLINK_RELOAD_LIMIT_MAX ; limit++)
3130+ if (limits_selected & BIT(limit))
3131+ break;
3132+ /* UAPI enables multiselection, but currently it is not used */
3133+ if (limits_selected != BIT(limit)) {
3134+ NL_SET_ERR_MSG_MOD(info->extack,
3135+ "Multiselection of limit is not supported");
3136+ return -EOPNOTSUPP;
3137+ }
3138+ if (!devlink_reload_limit_is_supported(devlink, limit)) {
3139+ NL_SET_ERR_MSG_MOD(info->extack,
3140+ "Requested limit is not supported by the driver");
3141+ return -EOPNOTSUPP;
3142+ }
3143+ if (devlink_reload_combination_is_invalid(action, limit)) {
3144+ NL_SET_ERR_MSG_MOD(info->extack,
3145+ "Requested limit is invalid for this action");
3146+ return -EINVAL;
3147+ }
3148+ }
3149+ err = devlink_reload(devlink, dest_net, action, limit, &actions_performed, info->extack);
30863150
30873151 if (dest_net)
30883152 put_net(dest_net);
@@ -3090,7 +3154,7 @@ static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info) · 1 unmodified line
30903154 if (err)
30913155 return err;
30923156 /* For backward compatibility generate reply only if attributes used by user */
3093− if (!info->attrs[DEVLINK_ATTR_RELOAD_ACTION])
3157+ if (!info->attrs[DEVLINK_ATTR_RELOAD_ACTION] && !info->attrs[DEVLINK_ATTR_RELOAD_LIMITS])
30943158 return 0;
30953159
30963160 return devlink_nl_reload_actions_performed_snd(devlink, actions_performed,
@@ -7347,6 +7411,7 @@ static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = { · 4250 unmodified lines
73477411 [DEVLINK_ATTR_PORT_FUNCTION] = { .type = NLA_NESTED },
73487412 [DEVLINK_ATTR_RELOAD_ACTION] = NLA_POLICY_RANGE(NLA_U8, DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
73497413 DEVLINK_RELOAD_ACTION_MAX),
7414+ [DEVLINK_ATTR_RELOAD_LIMITS] = NLA_POLICY_BITFIELD32(DEVLINK_RELOAD_LIMITS_VALID_MASK),
73507415 };
73517416
73527417 static const struct genl_small_ops devlink_nl_ops[] = {
@@ -7682,6 +7747,9 @@ static struct genl_family devlink_nl_family __ro_after_init = { · 329 unmodified lines
76827747
76837748 static bool devlink_reload_actions_valid(const struct devlink_ops *ops)
76847749 {
7750+ const struct devlink_reload_combination *comb;
7751+ int i;
7752+
76857753 if (!devlink_reload_supported(ops)) {
76867754 if (WARN_ON(ops->reload_actions))
76877755 return false;
@@ -7692,6 +7760,17 @@ static bool devlink_reload_actions_valid(const struct devlink_ops *ops) · 4 unmodified lines
76927760 ops->reload_actions & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) ||
76937761 ops->reload_actions >= BIT(__DEVLINK_RELOAD_ACTION_MAX)))
76947762 return false;
7763+
7764+ if (WARN_ON(ops->reload_limits & BIT(DEVLINK_RELOAD_LIMIT_UNSPEC) ||
7765+ ops->reload_limits >= BIT(__DEVLINK_RELOAD_LIMIT_MAX)))
7766+ return false;
7767+
7768+ for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++) {
7769+ comb = &devlink_reload_invalid_combinations[i];
7770+ if (ops->reload_actions == BIT(comb->action) &&
7771+ ops->reload_limits == BIT(comb->limit))
7772+ return false;
7773+ }
76957774 return true;
76967775 }
76977776
@@ -10056,6 +10135,7 @@ static void __net_exit devlink_pernet_pre_exit(struct net *net) · 2358 unmodified lines
1005610135 continue;
1005710136 err = devlink_reload(devlink, &init_net,
1005810137 DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
10138+ DEVLINK_RELOAD_LIMIT_UNSPEC,
1005910139 &actions_performed, NULL);
1006010140 if (err && err != -EOPNOTSUPP)
1006110141 pr_warn("Failed to reload devlink instance into init_net\n");