net/devlink/devl_internal.h

Source file repositories/reference/linux-study-clean/net/devlink/devl_internal.h

File Facts

System
Linux kernel
Corpus path
net/devlink/devl_internal.h
Extension
.h
Size
10778 bytes
Lines
334
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

const struct device_driver *dev_driver;
	possible_net_t _net;
	/* Serializes access to devlink instance specific objects such as
	 * port, sb, dpipe, resource, params, region, traps and more.
	 */
	struct mutex lock;
	struct lock_class_key lock_key;
	u8 reload_failed:1;
	refcount_t refcount;
	struct rcu_work rwork;
	struct devlink_rel *rel;
	struct xarray nested_rels;
	char priv[] __aligned(NETDEV_ALIGN);
};

extern struct xarray devlinks;
extern struct genl_family devlink_nl_family;

struct devlink *__devlink_alloc(const struct devlink_ops *ops, size_t priv_size,
				struct net *net, struct device *dev,
				const struct device_driver *dev_driver);

#define devl_warn(devlink, format, args...)				\
	do {								\
		if ((devlink)->dev)					\
			dev_warn((devlink)->dev, format, ##args);	\
		else							\
			pr_warn("devlink (%s): " format,		\
				devlink_dev_name(devlink), ##args);	\
	} while (0)

/* 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))

/* Iterate over devlink pointers which were possible to get reference to.
 * devlink_put() needs to be called for each iterated devlink pointer
 * in loop body in order to release the reference.
 */
#define devlinks_xa_for_each_registered_get(net, index, devlink)	\
	for (index = 0; (devlink = devlinks_xa_find_get(net, &index)); index++)

struct devlink *devlinks_xa_find_get(struct net *net, unsigned long *indexp);
struct devlink *devlinks_xa_lookup_get(struct net *net, unsigned long index);

static inline bool __devl_is_registered(struct devlink *devlink)
{
	return xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED);
}

static inline bool devl_is_registered(struct devlink *devlink)
{
	devl_assert_locked(devlink);
	return __devl_is_registered(devlink);
}

static inline void devl_dev_lock(struct devlink *devlink, bool dev_lock)
{
	if (dev_lock && devlink->dev)
		device_lock(devlink->dev);
	devl_lock(devlink);
}

static inline void devl_dev_unlock(struct devlink *devlink, bool dev_lock)
{
	devl_unlock(devlink);
	if (dev_lock && devlink->dev)
		device_unlock(devlink->dev);
}

typedef void devlink_rel_notify_cb_t(struct devlink *devlink, u32 obj_index);
typedef void devlink_rel_cleanup_cb_t(struct devlink *devlink, u32 obj_index,
				      u32 rel_index);

void devlink_rel_nested_in_clear(u32 rel_index);
int devlink_rel_nested_in_add(u32 *rel_index, u32 devlink_index,
			      u32 obj_index, devlink_rel_notify_cb_t *notify_cb,
			      devlink_rel_cleanup_cb_t *cleanup_cb,

Annotation

Implementation Notes