| .. SPDX-License-Identifier: GPL-2.0 | |
| ======================== | |
| Devlink Shared Instances | |
| ======================== | |
| Overview | |
| ======== | |
| Shared devlink instances allow multiple physical functions (PFs) on the same | |
| chip to share a devlink instance for chip-wide operations. | |
| Multiple PFs may reside on the same physical chip, running a single firmware. | |
| Some of the resources and configurations may be shared among these PFs. The | |
| shared devlink instance provides an object to pin configuration knobs on. | |
| There are two possible usage models: | |
| 1. The shared devlink instance is used alongside individual PF devlink | |
| instances, providing chip-wide configuration in addition to per-PF | |
| configuration. | |
| 2. The shared devlink instance is the only devlink instance, without | |
| per-PF instances. | |
| It is up to the driver to decide which usage model to use. | |
| The shared devlink instance is not backed by any struct *device*. | |
| Implementation | |
| ============== | |
| Architecture | |
| ------------ | |
| The implementation uses: | |
| * **Chip identification**: PFs are grouped by chip using a driver-specific identifier | |
| * **Shared instance management**: Global list of shared instances with reference counting | |
| API Functions | |
| ------------- | |
| The following functions are provided for managing shared devlink instances: | |
| * ``devlink_shd_get()``: Get or create a shared devlink instance identified by a string ID | |
| * ``devlink_shd_put()``: Release a reference on a shared devlink instance | |
| * ``devlink_shd_get_priv()``: Get private data from shared devlink instance | |
| Initialization Flow | |
| ------------------- | |
| 1. **PF calls shared devlink init** during driver probe | |
| 2. **Chip identification** using driver-specific method to determine device identity | |
| 3. **Get or create shared instance** using ``devlink_shd_get()``: | |
| * The function looks up existing instance by identifier | |
| * If none exists, creates new instance: | |
| - Allocates and registers devlink instance | |
| - Adds to global shared instances list | |
| - Increments reference count | |
| 4. **Set nested devlink instance** for the PF devlink instance using | |
| ``devl_nested_devlink_set()`` before registering the PF devlink instance | |
| Cleanup Flow | |
| ------------ | |
| 1. **Cleanup** when PF is removed | |
| 2. **Call** ``devlink_shd_put()`` to release reference (decrements reference count) | |
| 3. **Shared instance is automatically destroyed** when the last PF removes (reference count reaches zero) | |
| Chip Identification | |
| ------------------- | |
| PFs belonging to the same chip are identified using a driver-specific method. | |
| The driver is free to choose any identifier that is suitable for determining | |
| whether two PFs are part of the same device. Examples include: | |
| * **PCI VPD serial numbers**: Extract from PCI VPD | |
| * **Device tree properties**: Read chip identifier from device tree | |
| * **Other hardware-specific identifiers**: Any unique identifier that groups PFs by chip | |
| Locking | |
| ------- | |
| A global mutex (``shd_mutex``) protects the shared instances list during registration/deregistration. | |
| Similarly to other nested devlink instance relationships, devlink lock of | |
| the shared instance should be always taken after the devlink lock of PF. | |
| Reference Counting | |
| ------------------ | |
| Each shared devlink instance maintains a reference count (``refcount_t refcount``). | |
| The reference count is incremented when ``devlink_shd_get()`` is called and decremented | |
| when ``devlink_shd_put()`` is called. When the reference count reaches zero, the shared | |
| instance is automatically destroyed. |