Commit ea601e17 authored by Moshe Shemesh's avatar Moshe Shemesh Committed by David S. Miller

devlink: Add devlink notifications support for params

Add devlink_param_notify() function to support devlink param notifications.
Add notification call to devlink param set, register and unregister
functions.
Add devlink_param_value_changed() function to enable the driver notify
devlink on value change. Driver should use this function after value was
changed on any configuration mode part to driverinit.
Signed-off-by: default avatarMoshe Shemesh <moshe@mellanox.com>
Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ec01aeb1
...@@ -507,6 +507,7 @@ int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id, ...@@ -507,6 +507,7 @@ int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id,
union devlink_param_value *init_val); union devlink_param_value *init_val);
int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id, int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
union devlink_param_value init_val); union devlink_param_value init_val);
void devlink_param_value_changed(struct devlink *devlink, u32 param_id);
#else #else
...@@ -729,6 +730,12 @@ devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id, ...@@ -729,6 +730,12 @@ devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
static inline void
devlink_param_value_changed(struct devlink *devlink, u32 param_id)
{
return -EOPNOTSUPP;
}
#endif #endif
#endif /* _NET_DEVLINK_H_ */ #endif /* _NET_DEVLINK_H_ */
...@@ -80,6 +80,8 @@ enum devlink_command { ...@@ -80,6 +80,8 @@ enum devlink_command {
DEVLINK_CMD_PARAM_GET, /* can dump */ DEVLINK_CMD_PARAM_GET, /* can dump */
DEVLINK_CMD_PARAM_SET, DEVLINK_CMD_PARAM_SET,
DEVLINK_CMD_PARAM_NEW,
DEVLINK_CMD_PARAM_DEL,
/* add new commands above here */ /* add new commands above here */
__DEVLINK_CMD_MAX, __DEVLINK_CMD_MAX,
......
...@@ -2828,6 +2828,28 @@ static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink, ...@@ -2828,6 +2828,28 @@ static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink,
return -EMSGSIZE; return -EMSGSIZE;
} }
static void devlink_param_notify(struct devlink *devlink,
struct devlink_param_item *param_item,
enum devlink_command cmd)
{
struct sk_buff *msg;
int err;
WARN_ON(cmd != DEVLINK_CMD_PARAM_NEW && cmd != DEVLINK_CMD_PARAM_DEL);
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg)
return;
err = devlink_nl_param_fill(msg, devlink, param_item, cmd, 0, 0, 0);
if (err) {
nlmsg_free(msg);
return;
}
genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
}
static int devlink_nl_cmd_param_get_dumpit(struct sk_buff *msg, static int devlink_nl_cmd_param_get_dumpit(struct sk_buff *msg,
struct netlink_callback *cb) struct netlink_callback *cb)
{ {
...@@ -3019,6 +3041,7 @@ static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb, ...@@ -3019,6 +3041,7 @@ static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb,
return err; return err;
} }
devlink_param_notify(devlink, param_item, DEVLINK_CMD_PARAM_NEW);
return 0; return 0;
} }
...@@ -3042,6 +3065,7 @@ static int devlink_param_register_one(struct devlink *devlink, ...@@ -3042,6 +3065,7 @@ static int devlink_param_register_one(struct devlink *devlink,
param_item->param = param; param_item->param = param;
list_add_tail(&param_item->list, &devlink->param_list); list_add_tail(&param_item->list, &devlink->param_list);
devlink_param_notify(devlink, param_item, DEVLINK_CMD_PARAM_NEW);
return 0; return 0;
} }
...@@ -3053,6 +3077,7 @@ static void devlink_param_unregister_one(struct devlink *devlink, ...@@ -3053,6 +3077,7 @@ static void devlink_param_unregister_one(struct devlink *devlink,
param_item = devlink_param_find_by_name(&devlink->param_list, param_item = devlink_param_find_by_name(&devlink->param_list,
param->name); param->name);
WARN_ON(!param_item); WARN_ON(!param_item);
devlink_param_notify(devlink, param_item, DEVLINK_CMD_PARAM_DEL);
list_del(&param_item->list); list_del(&param_item->list);
kfree(param_item); kfree(param_item);
} }
...@@ -4039,10 +4064,35 @@ int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id, ...@@ -4039,10 +4064,35 @@ int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
param_item->driverinit_value = init_val; param_item->driverinit_value = init_val;
param_item->driverinit_value_valid = true; param_item->driverinit_value_valid = true;
devlink_param_notify(devlink, param_item, DEVLINK_CMD_PARAM_NEW);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_set); EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_set);
/**
* devlink_param_value_changed - notify devlink on a parameter's value
* change. Should be called by the driver
* right after the change.
*
* @devlink: devlink
* @param_id: parameter ID
*
* This function should be used by the driver to notify devlink on value
* change, excluding driverinit configuration mode.
* For driverinit configuration mode driver should use the function
* devlink_param_driverinit_value_set() instead.
*/
void devlink_param_value_changed(struct devlink *devlink, u32 param_id)
{
struct devlink_param_item *param_item;
param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
WARN_ON(!param_item);
devlink_param_notify(devlink, param_item, DEVLINK_CMD_PARAM_NEW);
}
EXPORT_SYMBOL_GPL(devlink_param_value_changed);
static int __init devlink_module_init(void) static int __init devlink_module_init(void)
{ {
return genl_register_family(&devlink_nl_family); return genl_register_family(&devlink_nl_family);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment