diff options
author | Leon Romanovsky <leonro@nvidia.com> | 2021-10-12 16:15:23 +0300 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2021-10-12 16:29:17 -0700 |
commit | b88f7b1203bf481af58291c28957aaab09503f43 (patch) | |
tree | 8d7809392396498d9f59fe2e0dea941e0cfc1e3e | |
parent | 2bc50987dc1f467551f2ca537239016915256f6d (diff) |
devlink: Annotate devlink API calls
Initial annotation patch to separate calls that needs to be executed
before or after devlink_register().
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r-- | net/core/devlink.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/net/core/devlink.c b/net/core/devlink.c index e9e908c4cfb4..276e1e421eb4 100644 --- a/net/core/devlink.c +++ b/net/core/devlink.c @@ -152,6 +152,22 @@ static const struct nla_policy devlink_function_nl_policy[DEVLINK_PORT_FUNCTION_ static DEFINE_XARRAY_FLAGS(devlinks, XA_FLAGS_ALLOC); #define DEVLINK_REGISTERED XA_MARK_1 +/* devlink instances are open to the access from the user space after + * devlink_register() call. Such logical barrier allows us to have certain + * expectations related to locking. + * + * Before *_register() - we are in initialization stage and no parallel + * access possible to the devlink instance. All drivers perform that phase + * by implicitly holding device_lock. + * + * After *_register() - users and driver can access devlink instance at + * the same time. + */ +#define ASSERT_DEVLINK_REGISTERED(d) \ + WARN_ON_ONCE(!xa_get_mark(&devlinks, (d)->index, DEVLINK_REGISTERED)) +#define ASSERT_DEVLINK_NOT_REGISTERED(d) \ + WARN_ON_ONCE(xa_get_mark(&devlinks, (d)->index, DEVLINK_REGISTERED)) + /* devlink_mutex * * An overall lock guarding every operation coming from userspace. @@ -9113,6 +9129,10 @@ static void devlink_notify_unregister(struct devlink *devlink) */ void devlink_register(struct devlink *devlink) { + ASSERT_DEVLINK_NOT_REGISTERED(devlink); + /* Make sure that we are in .probe() routine */ + device_lock_assert(devlink->dev); + mutex_lock(&devlink_mutex); xa_set_mark(&devlinks, devlink->index, DEVLINK_REGISTERED); devlink_notify_register(devlink); @@ -9127,6 +9147,10 @@ EXPORT_SYMBOL_GPL(devlink_register); */ void devlink_unregister(struct devlink *devlink) { + ASSERT_DEVLINK_REGISTERED(devlink); + /* Make sure that we are in .remove() routine */ + device_lock_assert(devlink->dev); + devlink_put(devlink); wait_for_completion(&devlink->comp); @@ -9181,6 +9205,8 @@ EXPORT_SYMBOL_GPL(devlink_reload_disable); */ void devlink_free(struct devlink *devlink) { + ASSERT_DEVLINK_NOT_REGISTERED(devlink); + mutex_destroy(&devlink->reporters_lock); mutex_destroy(&devlink->lock); WARN_ON(!list_empty(&devlink->trap_policer_list)); |