devlink: Add devlink notifications support for params
authorMoshe Shemesh <moshe@mellanox.com>
Wed, 4 Jul 2018 11:30:32 +0000 (14:30 +0300)
committerDavid S. Miller <davem@davemloft.net>
Thu, 5 Jul 2018 10:58:35 +0000 (19:58 +0900)
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: Moshe Shemesh <moshe@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/devlink.h
include/uapi/linux/devlink.h
net/core/devlink.c

index 3302e43b09a4e244f34d22de70f900111a084458..792edaa996bac1ef897b1048832882da20f2fc9e 100644 (file)
@@ -507,6 +507,7 @@ int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id,
                                       union devlink_param_value *init_val);
 int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
                                       union devlink_param_value init_val);
+void devlink_param_value_changed(struct devlink *devlink, u32 param_id);
 
 #else
 
@@ -729,6 +730,12 @@ devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
        return -EOPNOTSUPP;
 }
 
+static inline void
+devlink_param_value_changed(struct devlink *devlink, u32 param_id)
+{
+       return -EOPNOTSUPP;
+}
+
 #endif
 
 #endif /* _NET_DEVLINK_H_ */
index ea0623e568f037a54e529449f8ab668159ad3fa1..68641fb56654fb1be0ecd266247f40936a65d0a2 100644 (file)
@@ -80,6 +80,8 @@ enum devlink_command {
 
        DEVLINK_CMD_PARAM_GET,          /* can dump */
        DEVLINK_CMD_PARAM_SET,
+       DEVLINK_CMD_PARAM_NEW,
+       DEVLINK_CMD_PARAM_DEL,
 
        /* add new commands above here */
        __DEVLINK_CMD_MAX,
index 3af08f4562b57cce238531171269929522b4a96e..89d948fd4727a9a4fb74188c33f3960e8bc2d653 100644 (file)
@@ -2828,6 +2828,28 @@ genlmsg_cancel:
        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,
                                           struct netlink_callback *cb)
 {
@@ -3019,6 +3041,7 @@ static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb,
                        return err;
        }
 
+       devlink_param_notify(devlink, param_item, DEVLINK_CMD_PARAM_NEW);
        return 0;
 }
 
@@ -3042,6 +3065,7 @@ static int devlink_param_register_one(struct devlink *devlink,
        param_item->param = param;
 
        list_add_tail(&param_item->list, &devlink->param_list);
+       devlink_param_notify(devlink, param_item, DEVLINK_CMD_PARAM_NEW);
        return 0;
 }
 
@@ -3053,6 +3077,7 @@ static void devlink_param_unregister_one(struct devlink *devlink,
        param_item = devlink_param_find_by_name(&devlink->param_list,
                                                param->name);
        WARN_ON(!param_item);
+       devlink_param_notify(devlink, param_item, DEVLINK_CMD_PARAM_DEL);
        list_del(&param_item->list);
        kfree(param_item);
 }
@@ -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_valid = true;
 
+       devlink_param_notify(devlink, param_item, DEVLINK_CMD_PARAM_NEW);
        return 0;
 }
 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)
 {
        return genl_register_family(&devlink_nl_family);