devlink: allow registering parameters after the instance
authorJakub Kicinski <kuba@kernel.org>
Fri, 6 Jan 2023 06:34:00 +0000 (22:34 -0800)
committerDavid S. Miller <davem@davemloft.net>
Fri, 6 Jan 2023 12:56:19 +0000 (12:56 +0000)
It's most natural to register the instance first and then its
subobjects. Now that we can use the instance lock to protect
the atomicity of all init - it should also be safe.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/devlink/leftover.c

index 491f821..1e23b2d 100644 (file)
@@ -5263,7 +5263,13 @@ static void devlink_param_notify(struct devlink *devlink,
        WARN_ON(cmd != DEVLINK_CMD_PARAM_NEW && cmd != DEVLINK_CMD_PARAM_DEL &&
                cmd != DEVLINK_CMD_PORT_PARAM_NEW &&
                cmd != DEVLINK_CMD_PORT_PARAM_DEL);
-       ASSERT_DEVLINK_REGISTERED(devlink);
+
+       /* devlink_notify_register() / devlink_notify_unregister()
+        * will replay the notifications if the params are added/removed
+        * outside of the lifetime of the instance.
+        */
+       if (!devl_is_registered(devlink))
+               return;
 
        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (!msg)
@@ -10915,8 +10921,6 @@ int devlink_params_register(struct devlink *devlink,
        const struct devlink_param *param = params;
        int i, err;
 
-       ASSERT_DEVLINK_NOT_REGISTERED(devlink);
-
        for (i = 0; i < params_count; i++, param++) {
                err = devlink_param_register(devlink, param);
                if (err)
@@ -10947,8 +10951,6 @@ void devlink_params_unregister(struct devlink *devlink,
        const struct devlink_param *param = params;
        int i;
 
-       ASSERT_DEVLINK_NOT_REGISTERED(devlink);
-
        for (i = 0; i < params_count; i++, param++)
                devlink_param_unregister(devlink, param);
 }
@@ -10968,8 +10970,6 @@ int devlink_param_register(struct devlink *devlink,
 {
        struct devlink_param_item *param_item;
 
-       ASSERT_DEVLINK_NOT_REGISTERED(devlink);
-
        WARN_ON(devlink_param_verify(param));
        WARN_ON(devlink_param_find_by_name(&devlink->param_list, param->name));
 
@@ -10985,6 +10985,7 @@ int devlink_param_register(struct devlink *devlink,
        param_item->param = param;
 
        list_add_tail(&param_item->list, &devlink->param_list);
+       devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
        return 0;
 }
 EXPORT_SYMBOL_GPL(devlink_param_register);
@@ -10999,11 +11000,10 @@ void devlink_param_unregister(struct devlink *devlink,
 {
        struct devlink_param_item *param_item;
 
-       ASSERT_DEVLINK_NOT_REGISTERED(devlink);
-
        param_item =
                devlink_param_find_by_name(&devlink->param_list, param->name);
        WARN_ON(!param_item);
+       devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_DEL);
        list_del(&param_item->list);
        kfree(param_item);
 }
@@ -11063,8 +11063,6 @@ int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
 {
        struct devlink_param_item *param_item;
 
-       ASSERT_DEVLINK_NOT_REGISTERED(devlink);
-
        param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
        if (!param_item)
                return -EINVAL;
@@ -11078,6 +11076,8 @@ int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
        else
                param_item->driverinit_value = init_val;
        param_item->driverinit_value_valid = true;
+
+       devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
        return 0;
 }
 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_set);