Messages in this thread Patch in this message | | | From | Oleksandr Mazur <> | Subject | [PATCH net-next 03/11] net: core: devlink: add port_params_ops for devlink port parameters altering | Date | Wed, 9 Jun 2021 18:15:53 +0300 |
| |
Current design makes it impossible to distinguish which port's parameter should get altered (set) or retrieved (get) whenever there's a single parameter registered within a few ports.
Change this by adding new devlink port parameter ops structure: - introduce structure port_params_ops that has callbacks for get/set/validate; - if devlink has registered port_params_ops, then upon every devlink port parameter get/set call invoke port parameters callback
Suggested-by: Vadym Kochan <vadym.kochan@plvision.eu> Signed-off-by: Oleksandr Mazur <oleksandr.mazur@plvision.eu> --- include/net/devlink.h | 23 ++++++++++++++++++++++ net/core/devlink.c | 44 +++++++++++++++++++++++++++++++++++-------- 2 files changed, 59 insertions(+), 8 deletions(-)
diff --git a/include/net/devlink.h b/include/net/devlink.h index b8c6bac067a6..1d687651260c 100644 --- a/include/net/devlink.h +++ b/include/net/devlink.h @@ -1191,6 +1191,28 @@ enum devlink_trap_group_generic_id { .min_burst = _min_burst, \ } +/** + * struct devlink_port_param_ops - devlink port parameters-specific ops + * @get: get port parameter value, used for runtime and permanent + * configuration modes + * @set: set port parameter value, used for runtime and permanent + * configuration modes + * @validate: validate input value is applicable (within value range, etc.) + * + * This struct should be used by the driver register port parameters ops, + * that would be used by the devlink subsystem to fetch (get) or alter (set) + * devlink port parameter. + */ +struct devlink_port_param_ops { + int (*get)(struct devlink_port *port, u32 id, + struct devlink_param_gset_ctx *ctx); + int (*set)(struct devlink_port *port, u32 id, + struct devlink_param_gset_ctx *ctx); + int (*validate)(struct devlink_port *port, u32 id, + union devlink_param_value val, + struct netlink_ext_ack *extack); +}; + struct devlink_ops { /** * @supported_flash_update_params: @@ -1463,6 +1485,7 @@ struct devlink_ops { struct devlink_port *port, enum devlink_port_fn_state state, struct netlink_ext_ack *extack); + const struct devlink_port_param_ops *port_param_ops; }; static inline void *devlink_priv(struct devlink *devlink) diff --git a/net/core/devlink.c b/net/core/devlink.c index 2baf8720bb48..79566a04083b 100644 --- a/net/core/devlink.c +++ b/net/core/devlink.c @@ -3923,6 +3923,7 @@ static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink, const struct devlink_param *param = param_item->param; struct devlink_param_gset_ctx ctx; struct nlattr *param_values_list; + struct devlink_port *dl_port; struct nlattr *param_attr; int nla_type; void *hdr; @@ -3941,7 +3942,20 @@ static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink, if (!param_item->published) continue; ctx.cmode = i; - err = devlink_param_get(devlink, param, &ctx); + if ((cmd == DEVLINK_CMD_PORT_PARAM_GET || + cmd == DEVLINK_CMD_PORT_PARAM_NEW || + cmd == DEVLINK_CMD_PORT_PARAM_DEL) && + devlink->ops->port_param_ops && + devlink->ops->port_param_ops->get) { + dl_port = devlink_port_get_by_index(devlink, + port_index); + err = devlink->ops->port_param_ops->get(dl_port, + param->id, + &ctx); + } else { + err = devlink_param_get(devlink, param, &ctx); + } + if (err) return err; param_value[i] = ctx.val; @@ -4201,6 +4215,7 @@ static int __devlink_nl_cmd_param_set_doit(struct devlink *devlink, struct devlink_param_item *param_item; const struct devlink_param *param; union devlink_param_value value; + struct devlink_port *dl_port; int err = 0; param_item = devlink_param_get_from_info(param_list, info); @@ -4234,13 +4249,28 @@ static int __devlink_nl_cmd_param_set_doit(struct devlink *devlink, param_item->driverinit_value = value; param_item->driverinit_value_valid = true; } else { - if (!param->set) - return -EOPNOTSUPP; ctx.val = value; ctx.cmode = cmode; - err = devlink_param_set(devlink, param, &ctx); - if (err) - return err; + + if ((cmd == DEVLINK_CMD_PORT_PARAM_SET || + cmd == DEVLINK_CMD_PORT_PARAM_NEW) && + devlink->ops->port_param_ops && + devlink->ops->port_param_ops->set) { + dl_port = devlink_port_get_by_index(devlink, + port_index); + err = devlink->ops->port_param_ops->set(dl_port, + param->id, + &ctx); + if (err) + return err; + } else { + if (!param->set) + return -EOPNOTSUPP; + + err = devlink_param_set(devlink, param, &ctx); + if (err) + return err; + } } devlink_param_notify(devlink, port_index, param_item, cmd); @@ -4269,8 +4299,6 @@ static int devlink_param_register_one(struct devlink *devlink, if (param->supported_cmodes == BIT(DEVLINK_PARAM_CMODE_DRIVERINIT)) WARN_ON(param->get || param->set); - else - WARN_ON(!param->get || !param->set); param_item = kzalloc(sizeof(*param_item), GFP_KERNEL); if (!param_item) -- 2.17.1
| |