summaryrefslogtreecommitdiff
path: root/net/core
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2021-06-23 15:46:25 -0700
committerDavid S. Miller <davem@davemloft.net>2021-06-23 15:46:25 -0700
commit35713d9b8f090d7a226e4aaeeb742265cde33c82 (patch)
tree97d736059ad5dd500ad2c0ab91f99b30c5355243 /net/core
parenta2f7dc00ea51a9dbb7c5b4ca8e508acb24f7ca8c (diff)
parenta3e5e5797faad0db319d106afaa31b9020fac44f (diff)
downloadlinux-stable-35713d9b8f090d7a226e4aaeeb742265cde33c82.tar.gz
Merge branch 'devlink-rate-limit-fixes'
Dmytro Linkin says: ==================== Fixes for devlink rate objects API Patch #1 fixes not decreased refcount of parent node for destroyed leaf object. Patch #2 fixes incorect eswitch mode check. Patch #3 protects list traversing with a lock. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/devlink.c17
1 files changed, 6 insertions, 11 deletions
diff --git a/net/core/devlink.c b/net/core/devlink.c
index 566ddd147633..8fdd04f00fd7 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -2709,23 +2709,16 @@ static int devlink_rate_nodes_check(struct devlink *devlink, u16 mode,
struct netlink_ext_ack *extack)
{
struct devlink_rate *devlink_rate;
- u16 old_mode;
- int err;
-
- if (!devlink->ops->eswitch_mode_get)
- return -EOPNOTSUPP;
- err = devlink->ops->eswitch_mode_get(devlink, &old_mode);
- if (err)
- return err;
-
- if (old_mode == mode)
- return 0;
+ /* Take the lock to sync with devlink_rate_nodes_destroy() */
+ mutex_lock(&devlink->lock);
list_for_each_entry(devlink_rate, &devlink->rate_list, list)
if (devlink_rate_is_node(devlink_rate)) {
+ mutex_unlock(&devlink->lock);
NL_SET_ERR_MSG_MOD(extack, "Rate node(s) exists.");
return -EBUSY;
}
+ mutex_unlock(&devlink->lock);
return 0;
}
@@ -9275,6 +9268,8 @@ void devlink_rate_leaf_destroy(struct devlink_port *devlink_port)
mutex_lock(&devlink->lock);
devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_DEL);
+ if (devlink_rate->parent)
+ refcount_dec(&devlink_rate->parent->refcnt);
list_del(&devlink_rate->list);
devlink_port->devlink_rate = NULL;
mutex_unlock(&devlink->lock);