diff options
author | David S. Miller <davem@davemloft.net> | 2021-06-23 15:46:25 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2021-06-23 15:46:25 -0700 |
commit | 35713d9b8f090d7a226e4aaeeb742265cde33c82 (patch) | |
tree | 97d736059ad5dd500ad2c0ab91f99b30c5355243 /net/core | |
parent | a2f7dc00ea51a9dbb7c5b4ca8e508acb24f7ca8c (diff) | |
parent | a3e5e5797faad0db319d106afaa31b9020fac44f (diff) | |
download | linux-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.c | 17 |
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); |