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
3947 3947
3948static int mlx4_devlink_reload_down(struct devlink *devlink, bool netns_change,3948static int mlx4_devlink_reload_down(struct devlink *devlink, bool netns_change,
3949 enum devlink_reload_action action,3949 enum devlink_reload_action action,
3950 enum devlink_reload_limit limit,
3950 struct netlink_ext_ack *extack)3951 struct netlink_ext_ack *extack)
3951{3952{
3952 struct mlx4_priv *priv = devlink_priv(devlink);3953 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
3964}3965}
3965 3966
3966static int mlx4_devlink_reload_up(struct devlink *devlink, enum devlink_reload_action action,3967static 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)
3968{3970{
3969 struct mlx4_priv *priv = devlink_priv(devlink);3971 struct mlx4_priv *priv = devlink_priv(devlink);
3970 struct mlx4_dev *dev = &priv->dev;3972 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
86 86
87static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change,87static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change,
88 enum devlink_reload_action action,88 enum devlink_reload_action action,
89 enum devlink_reload_limit limit,
89 struct netlink_ext_ack *extack)90 struct netlink_ext_ack *extack)
90{91{
91 struct mlx5_core_dev *dev = devlink_priv(devlink);92 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
95}96}
96 97
97static int mlx5_devlink_reload_up(struct devlink *devlink, enum devlink_reload_action action,98static 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)
99{101{
100 struct mlx5_core_dev *dev = devlink_priv(devlink);102 struct mlx5_core_dev *dev = devlink_priv(devlink);
101 103
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
1415static int1415static int
1416mlxsw_devlink_core_bus_device_reload_down(struct devlink *devlink,1416mlxsw_devlink_core_bus_device_reload_down(struct devlink *devlink,
1417 bool netns_change, enum devlink_reload_action action,1417 bool netns_change, enum devlink_reload_action action,
1418 enum devlink_reload_limit limit,
1418 struct netlink_ext_ack *extack)1419 struct netlink_ext_ack *extack)
1419{1420{
1420 struct mlxsw_core *mlxsw_core = devlink_priv(devlink);1421 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
1428 1429
1429static int1430static int
1430mlxsw_devlink_core_bus_device_reload_up(struct devlink *devlink, enum devlink_reload_action action,1431mlxsw_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)
1432{1434{
1433 struct mlxsw_core *mlxsw_core = devlink_priv(devlink);1435 struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
1434 1436
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
701static void nsim_dev_reload_destroy(struct nsim_dev *nsim_dev);701static void nsim_dev_reload_destroy(struct nsim_dev *nsim_dev);
702 702
703static int nsim_dev_reload_down(struct devlink *devlink, bool netns_change,703static 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)
705{706{
706 struct nsim_dev *nsim_dev = devlink_priv(devlink);707 struct nsim_dev *nsim_dev = devlink_priv(devlink);
707 708
@@ -718,7 +719,8 @@ static int nsim_dev_reload_down(struct devlink *devlink, bool netns_change, · 10 unmodified lines
718}719}
719 720
720static int nsim_dev_reload_up(struct devlink *devlink, enum devlink_reload_action action,721static 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)
722{724{
723 struct nsim_dev *nsim_dev = devlink_priv(devlink);725 struct nsim_dev *nsim_dev = devlink_priv(devlink);
724 726
include/net/devlink.h+6−2
@@ -1151,10 +1151,14 @@ struct devlink_ops { · 1150 unmodified lines
1151 */1151 */
1152 u32 supported_flash_update_params;1152 u32 supported_flash_update_params;
1153 unsigned long reload_actions;1153 unsigned long reload_actions;
1154 unsigned long reload_limits;
1154 int (*reload_down)(struct devlink *devlink, bool netns_change,1155 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);
1156 int (*reload_up)(struct devlink *devlink, enum devlink_reload_action action,1159 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);
1158 int (*port_type_set)(struct devlink_port *devlink_port,1162 int (*port_type_set)(struct devlink_port *devlink_port,
1159 enum devlink_port_type port_type);1163 enum devlink_port_type port_type);
1160 int (*port_split)(struct devlink *devlink, unsigned int port_index,1164 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
311 DEVLINK_RELOAD_ACTION_MAX = __DEVLINK_RELOAD_ACTION_MAX - 1311 DEVLINK_RELOAD_ACTION_MAX = __DEVLINK_RELOAD_ACTION_MAX - 1
312};312};
313 313
314enum 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
314enum devlink_attr {327enum devlink_attr {
315 /* don't change the order or add anything between, this is ABI! */328 /* don't change the order or add anything between, this is ABI! */
316 DEVLINK_ATTR_UNSPEC,329 DEVLINK_ATTR_UNSPEC,
@@ -505,6 +518,7 @@ enum devlink_attr { · 188 unmodified lines
505 518
506 DEVLINK_ATTR_RELOAD_ACTION, /* u8 */519 DEVLINK_ATTR_RELOAD_ACTION, /* u8 */
507 DEVLINK_ATTR_RELOAD_ACTIONS_PERFORMED, /* bitfield32 */520 DEVLINK_ATTR_RELOAD_ACTIONS_PERFORMED, /* bitfield32 */
521 DEVLINK_ATTR_RELOAD_LIMITS, /* bitfield32 */
508 522
509 /* add new attributes above here, update the policy in devlink.c */523 /* add new attributes above here, update the policy in devlink.c */
510 524
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
479 return 0;479 return 0;
480}480}
481 481
482struct devlink_reload_combination {
483 enum devlink_reload_action action;
484 enum devlink_reload_limit limit;
485};
486
487static 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
495static bool
496devlink_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
482static bool508static bool
483devlink_reload_action_is_supported(struct devlink *devlink, enum devlink_reload_action action)509devlink_reload_action_is_supported(struct devlink *devlink, enum devlink_reload_action action)
484{510{
485 return test_bit(action, &devlink->ops->reload_actions);511 return test_bit(action, &devlink->ops->reload_actions);
486}512}
487 513
514static bool
515devlink_reload_limit_is_supported(struct devlink *devlink, enum devlink_reload_limit limit)
516{
517 return test_bit(limit, &devlink->ops->reload_limits);
518}
519
488static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,520static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
489 enum devlink_command cmd, u32 portid,521 enum devlink_command cmd, u32 portid,
490 u32 seq, int flags)522 u32 seq, int flags)
@@ -2990,22 +3022,22 @@ bool devlink_is_reload_failed(const struct devlink *devlink) · 2499 unmodified lines
2990EXPORT_SYMBOL_GPL(devlink_is_reload_failed);3022EXPORT_SYMBOL_GPL(devlink_is_reload_failed);
2991 3023
2992static int devlink_reload(struct devlink *devlink, struct net *dest_net,3024static int devlink_reload(struct devlink *devlink, struct net *dest_net,
2993 enum devlink_reload_action action, u32 *actions_performed,3025 enum devlink_reload_action action, enum devlink_reload_limit limit,
2994 struct netlink_ext_ack *extack)3026 u32 *actions_performed, struct netlink_ext_ack *extack)
2995{3027{
2996 int err;3028 int err;
2997 3029
2998 if (!devlink->reload_enabled)3030 if (!devlink->reload_enabled)
2999 return -EOPNOTSUPP;3031 return -EOPNOTSUPP;
3000 3032
3001 err = devlink->ops->reload_down(devlink, !!dest_net, action, extack);3033 err = devlink->ops->reload_down(devlink, !!dest_net, action, limit, extack);
3002 if (err)3034 if (err)
3003 return err;3035 return err;
3004 3036
3005 if (dest_net && !net_eq(dest_net, devlink_net(devlink)))3037 if (dest_net && !net_eq(dest_net, devlink_net(devlink)))
3006 devlink_reload_netns_change(devlink, dest_net);3038 devlink_reload_netns_change(devlink, dest_net);
3007 3039
3008 err = devlink->ops->reload_up(devlink, action, actions_performed, extack);3040 err = devlink->ops->reload_up(devlink, action, limit, actions_performed, extack);
3009 devlink_reload_failed_set(devlink, !!err);3041 devlink_reload_failed_set(devlink, !!err);
3010 if (err)3042 if (err)
3011 return err;3043 return err;
@@ -3050,6 +3082,7 @@ static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info) · 38 unmodified lines
3050{3082{
3051 struct devlink *devlink = info->user_ptr[0];3083 struct devlink *devlink = info->user_ptr[0];
3052 enum devlink_reload_action action;3084 enum devlink_reload_action action;
3085 enum devlink_reload_limit limit;
3053 struct net *dest_net = NULL;3086 struct net *dest_net = NULL;
3054 u32 actions_performed;3087 u32 actions_performed;
3055 int err;3088 int err;
@@ -3082,7 +3115,38 @@ static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info) · 26 unmodified lines
3082 return -EOPNOTSUPP;3115 return -EOPNOTSUPP;
3083 }3116 }
3084 3117
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);
3086 3150
3087 if (dest_net)3151 if (dest_net)
3088 put_net(dest_net);3152 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
3090 if (err)3154 if (err)
3091 return err;3155 return err;
3092 /* For backward compatibility generate reply only if attributes used by user */3156 /* 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])
3094 return 0;3158 return 0;
3095 3159
3096 return devlink_nl_reload_actions_performed_snd(devlink, actions_performed,3160 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
7347 [DEVLINK_ATTR_PORT_FUNCTION] = { .type = NLA_NESTED },7411 [DEVLINK_ATTR_PORT_FUNCTION] = { .type = NLA_NESTED },
7348 [DEVLINK_ATTR_RELOAD_ACTION] = NLA_POLICY_RANGE(NLA_U8, DEVLINK_RELOAD_ACTION_DRIVER_REINIT,7412 [DEVLINK_ATTR_RELOAD_ACTION] = NLA_POLICY_RANGE(NLA_U8, DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
7349 DEVLINK_RELOAD_ACTION_MAX),7413 DEVLINK_RELOAD_ACTION_MAX),
7414 [DEVLINK_ATTR_RELOAD_LIMITS] = NLA_POLICY_BITFIELD32(DEVLINK_RELOAD_LIMITS_VALID_MASK),
7350};7415};
7351 7416
7352static const struct genl_small_ops devlink_nl_ops[] = {7417static 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
7682 7747
7683static bool devlink_reload_actions_valid(const struct devlink_ops *ops)7748static bool devlink_reload_actions_valid(const struct devlink_ops *ops)
7684{7749{
7750 const struct devlink_reload_combination *comb;
7751 int i;
7752
7685 if (!devlink_reload_supported(ops)) {7753 if (!devlink_reload_supported(ops)) {
7686 if (WARN_ON(ops->reload_actions))7754 if (WARN_ON(ops->reload_actions))
7687 return false;7755 return false;
@@ -7692,6 +7760,17 @@ static bool devlink_reload_actions_valid(const struct devlink_ops *ops) · 4 unmodified lines
7692 ops->reload_actions & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) ||7760 ops->reload_actions & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) ||
7693 ops->reload_actions >= BIT(__DEVLINK_RELOAD_ACTION_MAX)))7761 ops->reload_actions >= BIT(__DEVLINK_RELOAD_ACTION_MAX)))
7694 return false;7762 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 }
7695 return true;7774 return true;
7696}7775}
7697 7776
@@ -10056,6 +10135,7 @@ static void __net_exit devlink_pernet_pre_exit(struct net *net) · 2358 unmodified lines
10056 continue;10135 continue;
10057 err = devlink_reload(devlink, &init_net,10136 err = devlink_reload(devlink, &init_net,
10058 DEVLINK_RELOAD_ACTION_DRIVER_REINIT,10137 DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
10138 DEVLINK_RELOAD_LIMIT_UNSPEC,
10059 &actions_performed, NULL);10139 &actions_performed, NULL);
10060 if (err && err != -EOPNOTSUPP)10140 if (err && err != -EOPNOTSUPP)
10061 pr_warn("Failed to reload devlink instance into init_net\n");10141 pr_warn("Failed to reload devlink instance into init_net\n");