From: Saeed Mahameed Port params infrastructure is incomplete and needs a bit of plumbing to support port params commands from netlink. Introduce port params registration API, very similar to current devlink params API, add the params xarray to devlink_port structure and decouple devlink params registration routines from the devlink structure. Issue: 3962500 Change-Id: I5b88aaa13e4a9a386b1441690bb6a6a304651fac Issue: 2114292 Signed-off-by: Saeed Mahameed Reviewed-by: Jiri Pirko --- include/net/devlink.h | 14 ++++ net/devlink/param.c | 151 ++++++++++++++++++++++++++++++++++-------- net/devlink/port.c | 3 + 3 files changed, 141 insertions(+), 27 deletions(-) diff --git a/include/net/devlink.h b/include/net/devlink.h index c10afb28738a..6861ee3af546 100644 --- a/include/net/devlink.h +++ b/include/net/devlink.h @@ -125,6 +125,7 @@ struct devlink_port { struct list_head region_list; struct devlink *devlink; const struct devlink_port_ops *ops; + struct xarray params; unsigned int index; spinlock_t type_lock; /* Protects type and type_eth/ib * structures consistency. @@ -1827,6 +1828,19 @@ void devl_params_unregister(struct devlink *devlink, void devlink_params_unregister(struct devlink *devlink, const struct devlink_param *params, size_t params_count); +int devl_port_params_register(struct devlink_port *devlink_port, + const struct devlink_param *params, + size_t params_count); +int devlink_port_params_register(struct devlink_port *devlink_port, + const struct devlink_param *params, + size_t params_count); +void devl_port_params_unregister(struct devlink_port *devlink_port, + const struct devlink_param *params, + size_t params_count); +void devlink_port_params_unregister(struct devlink_port *devlink_port, + const struct devlink_param *params, + size_t params_count); + int devl_param_driverinit_value_get(struct devlink *devlink, u32 param_id, union devlink_param_value *val); void devl_param_driverinit_value_set(struct devlink *devlink, u32 param_id, diff --git a/net/devlink/param.c b/net/devlink/param.c index fcb59763530a..3103091c2da7 100644 --- a/net/devlink/param.c +++ b/net/devlink/param.c @@ -590,13 +590,16 @@ static int devlink_param_verify(const struct devlink_param *param) } static int devlink_param_register(struct devlink *devlink, + struct devlink_port *devlink_port, + struct xarray *params_arr, const struct devlink_param *param) { struct devlink_param_item *param_item; + enum devlink_command cmd; int err; WARN_ON(devlink_param_verify(param)); - WARN_ON(devlink_param_find_by_name(&devlink->params, param->name)); + WARN_ON(devlink_param_find_by_name(params_arr, param->name)); if (param->supported_cmodes == BIT(DEVLINK_PARAM_CMODE_DRIVERINIT)) WARN_ON(param->get || param->set); @@ -609,11 +612,13 @@ static int devlink_param_register(struct devlink *devlink, param_item->param = param; - err = xa_insert(&devlink->params, param->id, param_item, GFP_KERNEL); + err = xa_insert(params_arr, param->id, param_item, GFP_KERNEL); if (err) goto err_xa_insert; - devlink_param_notify(devlink, NULL, param_item, DEVLINK_CMD_PARAM_NEW); + cmd = devlink_port ? DEVLINK_CMD_PORT_PARAM_NEW : DEVLINK_CMD_PARAM_NEW; + devlink_param_notify(devlink, devlink_port, param_item, cmd); + return 0; err_xa_insert: @@ -622,30 +627,28 @@ static int devlink_param_register(struct devlink *devlink, } static void devlink_param_unregister(struct devlink *devlink, + struct devlink_port *devlink_port, + struct xarray *params_arr, const struct devlink_param *param) { struct devlink_param_item *param_item; + enum devlink_command cmd; - param_item = devlink_param_find_by_id(&devlink->params, param->id); + param_item = devlink_param_find_by_id(params_arr, param->id); if (WARN_ON(!param_item)) return; - devlink_param_notify(devlink, NULL, param_item, DEVLINK_CMD_PARAM_DEL); - xa_erase(&devlink->params, param->id); + + cmd = devlink_port ? DEVLINK_CMD_PORT_PARAM_DEL : DEVLINK_CMD_PARAM_DEL; + devlink_param_notify(devlink, devlink_port, param_item, cmd); + xa_erase(params_arr, param->id); kfree(param_item); } -/** - * devl_params_register - register configuration parameters - * - * @devlink: devlink - * @params: configuration parameters array - * @params_count: number of parameters provided - * - * Register the configuration parameters supported by the driver. - */ -int devl_params_register(struct devlink *devlink, - const struct devlink_param *params, - size_t params_count) +static int __devlink_params_register(struct devlink *devlink, + struct devlink_port *devlink_port, + struct xarray *params_arr, + const struct devlink_param *params, + size_t params_count) { const struct devlink_param *param = params; int i, err; @@ -653,10 +656,12 @@ int devl_params_register(struct devlink *devlink, lockdep_assert_held(&devlink->lock); for (i = 0; i < params_count; i++, param++) { - err = devlink_param_register(devlink, param); + err = devlink_param_register(devlink, devlink_port, params_arr, + param); if (err) goto rollback; } + return 0; rollback: @@ -664,9 +669,28 @@ int devl_params_register(struct devlink *devlink, return err; for (param--; i > 0; i--, param--) - devlink_param_unregister(devlink, param); + devlink_param_unregister(devlink, devlink_port, params_arr, + param); + return err; } + +/** + * devl_params_register - register configuration parameters + * + * @devlink: devlink + * @params: configuration parameters array + * @params_count: number of parameters provided + * + * Register the configuration parameters supported by the driver. + */ +int devl_params_register(struct devlink *devlink, + const struct devlink_param *params, + size_t params_count) +{ + return __devlink_params_register(devlink, NULL, &devlink->params, + params, params_count); +} EXPORT_SYMBOL_GPL(devl_params_register); int devlink_params_register(struct devlink *devlink, @@ -682,6 +706,22 @@ int devlink_params_register(struct devlink *devlink, } EXPORT_SYMBOL_GPL(devlink_params_register); +static void __devlink_params_unregister(struct devlink *devlink, + struct devlink_port *devlink_port, + struct xarray *params_arr, + const struct devlink_param *params, + size_t params_count) +{ + const struct devlink_param *param = params; + int i; + + lockdep_assert_held(&devlink->lock); + + for (i = 0; i < params_count; i++, param++) + devlink_param_unregister(devlink, devlink_port, params_arr, + param); +} + /** * devl_params_unregister - unregister configuration parameters * @devlink: devlink @@ -692,13 +732,8 @@ void devl_params_unregister(struct devlink *devlink, const struct devlink_param *params, size_t params_count) { - const struct devlink_param *param = params; - int i; - - lockdep_assert_held(&devlink->lock); - - for (i = 0; i < params_count; i++, param++) - devlink_param_unregister(devlink, param); + __devlink_params_unregister(devlink, NULL, &devlink->params, + params, params_count); } EXPORT_SYMBOL_GPL(devl_params_unregister); @@ -712,6 +747,68 @@ void devlink_params_unregister(struct devlink *devlink, } EXPORT_SYMBOL_GPL(devlink_params_unregister); +/** + * devl_port_params_register - register configuration parameters for port + * + * @devlink_port: devlink port + * @params: configuration parameters array + * @params_count: number of parameters provided + * + * Register the configuration parameters supported by the driver for the + * specific port. + */ +int devl_port_params_register(struct devlink_port *devlink_port, + const struct devlink_param *params, + size_t params_count) +{ + return __devlink_params_register(devlink_port->devlink, + devlink_port, + &devlink_port->params, + params, params_count); +} +EXPORT_SYMBOL_GPL(devl_port_params_register); + +/** + * devl_port_params_unregister - unregister configuration parameters for + * devlink port + * + * @devlink_port: devlink port + * @params: configuration parameters to unregister + * @params_count: number of parameters provided + */ +void devl_port_params_unregister(struct devlink_port *devlink_port, + const struct devlink_param *params, + size_t params_count) +{ + __devlink_params_unregister(devlink_port->devlink, devlink_port, + &devlink_port->params, + params, params_count); +} +EXPORT_SYMBOL_GPL(devl_port_params_unregister); + +int devlink_port_params_register(struct devlink_port *devlink_port, + const struct devlink_param *params, + size_t params_count) +{ + int err; + + devl_lock(devlink_port->devlink); + err = devl_port_params_register(devlink_port, params, params_count); + devl_unlock(devlink_port->devlink); + return err; +} +EXPORT_SYMBOL_GPL(devlink_port_params_register); + +void devlink_port_params_unregister(struct devlink_port *devlink_port, + const struct devlink_param *params, + size_t params_count) +{ + devl_lock(devlink_port->devlink); + devl_port_params_unregister(devlink_port, params, params_count); + devl_unlock(devlink_port->devlink); +} +EXPORT_SYMBOL_GPL(devlink_port_params_unregister); + /** * devl_param_driverinit_value_get - get configuration parameter * value for driver initializing diff --git a/net/devlink/port.c b/net/devlink/port.c index 939081a0e615..39bba3f7a1f9 100644 --- a/net/devlink/port.c +++ b/net/devlink/port.c @@ -1075,6 +1075,8 @@ int devl_port_register_with_ops(struct devlink *devlink, devlink_port->registered = true; devlink_port->index = port_index; devlink_port->ops = ops ? ops : &devlink_port_dummy_ops; + xa_init_flags(&devlink_port->params, XA_FLAGS_ALLOC); + spin_lock_init(&devlink_port->type_lock); INIT_LIST_HEAD(&devlink_port->reporter_list); err = xa_insert(&devlink->ports, port_index, devlink_port, GFP_KERNEL); @@ -1134,6 +1136,7 @@ void devl_port_unregister(struct devlink_port *devlink_port) devlink_port_type_warn_cancel(devlink_port); devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL); xa_erase(&devlink_port->devlink->ports, devlink_port->index); + xa_destroy(&devlink_port->params); WARN_ON(!list_empty(&devlink_port->reporter_list)); devlink_port->registered = false; } -- 2.50.0