Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

devlink: expose get/put functions

Allow those who hold implicit reference on a devlink instance
to try to take a full ref on it. This will be used from netdev
code which has an implicit ref because of driver call ordering.

Note that after recent changes devlink_unregister() may happen
before netdev unregister, but devlink_free() should still happen
after, so we are safe to try, but we can't just refcount_inc()
and assume it's not zero.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Jakub Kicinski and committed by
David S. Miller
46db1b77 095cfcfe

+17 -3
+12
include/net/devlink.h
··· 1726 1726 1727 1727 #if IS_ENABLED(CONFIG_NET_DEVLINK) 1728 1728 1729 + struct devlink *__must_check devlink_try_get(struct devlink *devlink); 1730 + void devlink_put(struct devlink *devlink); 1731 + 1729 1732 void devlink_compat_running_version(struct net_device *dev, 1730 1733 char *buf, size_t len); 1731 1734 int devlink_compat_flash_update(struct net_device *dev, const char *file_name); ··· 1738 1735 struct netdev_phys_item_id *ppid); 1739 1736 1740 1737 #else 1738 + 1739 + static inline struct devlink *devlink_try_get(struct devlink *devlink) 1740 + { 1741 + return NULL; 1742 + } 1743 + 1744 + static inline void devlink_put(struct devlink *devlink) 1745 + { 1746 + } 1741 1747 1742 1748 static inline void 1743 1749 devlink_compat_running_version(struct net_device *dev, char *buf, size_t len)
+5 -3
net/core/devlink.c
··· 182 182 } 183 183 EXPORT_SYMBOL_GPL(devlink_net); 184 184 185 - static void devlink_put(struct devlink *devlink) 185 + void devlink_put(struct devlink *devlink) 186 186 { 187 187 if (refcount_dec_and_test(&devlink->refcount)) 188 188 complete(&devlink->comp); 189 189 } 190 190 191 - static bool __must_check devlink_try_get(struct devlink *devlink) 191 + struct devlink *__must_check devlink_try_get(struct devlink *devlink) 192 192 { 193 - return refcount_inc_not_zero(&devlink->refcount); 193 + if (refcount_inc_not_zero(&devlink->refcount)) 194 + return devlink; 195 + return NULL; 194 196 } 195 197 196 198 static struct devlink *devlink_get_from_attrs(struct net *net,