summaryrefslogtreecommitdiffstats
path: root/net/core/devlink.c
diff options
context:
space:
mode:
authorMichal Wilczynski <michal.wilczynski@intel.com>2022-11-15 11:48:18 +0100
committerJakub Kicinski <kuba@kernel.org>2022-11-18 06:41:26 +0100
commit04d674f04e32d4109f0ee505a8855a384481212d (patch)
treebdf6b3c0b938598b092da80c3981b7b89d5a318f /net/core/devlink.c
parentdevlink: Enable creation of the devlink-rate nodes from the driver (diff)
downloadlinux-04d674f04e32d4109f0ee505a8855a384481212d.tar.xz
linux-04d674f04e32d4109f0ee505a8855a384481212d.zip
devlink: Allow for devlink-rate nodes parent reassignment
Currently it's not possible to reassign the parent of the node using one command. As the previous commit introduced a way to export entire hierarchy from the driver, being able to modify and reassign parents become important. This way user might easily change QoS settings without interrupting traffic. Example command: devlink port function rate set pci/0000:4b:00.0/1 parent node_custom_1 This reassigns leaf node parent to node_custom_1. Signed-off-by: Michal Wilczynski <michal.wilczynski@intel.com> Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com> Reviewed-by: Jiri Pirko <jiri@nvidia.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to '')
-rw-r--r--net/core/devlink.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/net/core/devlink.c b/net/core/devlink.c
index 3dfee7cd9929..61d431578f5f 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -1887,10 +1887,8 @@ devlink_nl_rate_parent_node_set(struct devlink_rate *devlink_rate,
int err = -EOPNOTSUPP;
parent = devlink_rate->parent;
- if (parent && len) {
- NL_SET_ERR_MSG_MOD(info->extack, "Rate object already has parent.");
- return -EBUSY;
- } else if (parent && !len) {
+
+ if (parent && !len) {
if (devlink_rate_is_leaf(devlink_rate))
err = ops->rate_leaf_parent_set(devlink_rate, NULL,
devlink_rate->priv, NULL,
@@ -1904,7 +1902,7 @@ devlink_nl_rate_parent_node_set(struct devlink_rate *devlink_rate,
refcount_dec(&parent->refcnt);
devlink_rate->parent = NULL;
- } else if (!parent && len) {
+ } else if (len) {
parent = devlink_rate_node_get_by_name(devlink, parent_name);
if (IS_ERR(parent))
return -ENODEV;
@@ -1931,6 +1929,10 @@ devlink_nl_rate_parent_node_set(struct devlink_rate *devlink_rate,
if (err)
return err;
+ if (devlink_rate->parent)
+ /* we're reassigning to other parent in this case */
+ refcount_dec(&devlink_rate->parent->refcnt);
+
refcount_inc(&parent->refcnt);
devlink_rate->parent = parent;
}