net/devlink/sh_dev.c

Source file repositories/reference/linux-study-clean/net/devlink/sh_dev.c

File Facts

System
Linux kernel
Corpus path
net/devlink/sh_dev.c
Extension
.c
Size
4161 bytes
Lines
162
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 *driver)
{
	struct devlink_shd *shd;
	struct devlink *devlink;

	devlink = __devlink_alloc(ops, sizeof(struct devlink_shd) + priv_size,
				  &init_net, NULL, driver);
	if (!devlink)
		return NULL;
	shd = devlink_priv(devlink);

	shd->id = kstrdup(id, GFP_KERNEL);
	if (!shd->id)
		goto err_devlink_free;
	shd->priv_size = priv_size;
	refcount_set(&shd->refcount, 1);

	devl_lock(devlink);
	devl_register(devlink);
	devl_unlock(devlink);

	list_add_tail(&shd->list, &shd_list);

	return shd;

err_devlink_free:
	devlink_free(devlink);
	return NULL;
}

static void devlink_shd_destroy(struct devlink_shd *shd)
{
	struct devlink *devlink = priv_to_devlink(shd);

	list_del(&shd->list);
	devl_lock(devlink);
	devl_unregister(devlink);
	devl_unlock(devlink);
	kfree(shd->id);
	devlink_free(devlink);
}

/**
 * devlink_shd_get - Get or create a shared devlink instance
 * @id: Identifier string (e.g., serial number) for the shared instance
 * @ops: Devlink operations structure
 * @priv_size: Size of private data structure
 * @driver: Driver associated with the shared devlink instance
 *
 * Get an existing shared devlink instance identified by @id, or create
 * a new one if it doesn't exist. Return the devlink instance with a
 * reference held. The caller must call devlink_shd_put() when done.
 *
 * All callers sharing the same @id must pass identical @ops, @priv_size
 * and @driver. A mismatch triggers a warning and returns NULL.
 *
 * Return: Pointer to the shared devlink instance on success,
 *         NULL on failure
 */
struct devlink *devlink_shd_get(const char *id,
				const struct devlink_ops *ops,
				size_t priv_size,
				const struct device_driver *driver)
{
	struct devlink *devlink;
	struct devlink_shd *shd;

	mutex_lock(&shd_mutex);

	shd = devlink_shd_lookup(id);
	if (!shd) {
		shd = devlink_shd_create(id, ops, priv_size, driver);
		goto unlock;
	}

	devlink = priv_to_devlink(shd);
	if (WARN_ON_ONCE(devlink->ops != ops ||
			 shd->priv_size != priv_size ||
			 devlink->dev_driver != driver)) {
		shd = NULL;
		goto unlock;
	}
	refcount_inc(&shd->refcount);

unlock:
	mutex_unlock(&shd_mutex);
	return shd ? priv_to_devlink(shd) : NULL;
}
EXPORT_SYMBOL_GPL(devlink_shd_get);

Annotation

Implementation Notes