drivers/net/ethernet/mellanox/mlx5/core/sriov.c
Source file repositories/reference/linux-study-clean/drivers/net/ethernet/mellanox/mlx5/core/sriov.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ethernet/mellanox/mlx5/core/sriov.c- Extension
.c- Size
- 10833 bytes
- Lines
- 380
- Domain
- Driver Families
- Bucket
- drivers/net
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/pci.hlinux/mlx5/driver.hlinux/mlx5/vport.hmlx5_core.hmlx5_irq.heswitch.h
Detected Declarations
function Copyrightfunction mlx5_device_enable_sriovfunction mlx5_device_disable_sriovfunction mlx5_sriov_enablefunction mlx5_sriov_disablefunction mlx5_core_sriov_configurefunction mlx5_core_sriov_set_msix_vec_countfunction mlx5_sriov_attachfunction mlx5_sriov_detachfunction mlx5_get_max_vfsfunction mlx5_sriov_initfunction mlx5_sriov_cleanupfunction mlx5_sriov_blocking_notifier_unregisterfunction mlx5_sriov_blocking_notifier_registerexport mlx5_sriov_blocking_notifier_unregisterexport mlx5_sriov_blocking_notifier_register
Annotated Snippet
if (err) {
mlx5_core_warn(dev, "failed to enable VF %d (%d)\n", vf, err);
continue;
}
err = mlx5_set_msix_vec_count(dev, vf + 1, num_msix_count);
if (err) {
mlx5_core_warn(dev,
"failed to set MSI-X vector counts VF %d, err %d\n",
vf, err);
continue;
}
sriov->vfs_ctx[vf].enabled = 1;
if (MLX5_CAP_GEN(dev, port_type) == MLX5_CAP_PORT_TYPE_IB) {
vport_num = mlx5_core_ec_sriov_enabled(dev) ?
mlx5_core_ec_vf_vport_base(dev) + vf
: vf + 1;
err = sriov_restore_guids(dev, vf, vport_num);
if (err) {
mlx5_core_warn(dev,
"failed to restore VF %d settings, err %d\n",
vf, err);
continue;
}
}
mlx5_core_dbg(dev, "successfully enabled VF* %d\n", vf);
}
return 0;
}
static void
mlx5_device_disable_sriov(struct mlx5_core_dev *dev, int num_vfs, bool clear_vf, bool num_vf_change)
{
struct mlx5_core_sriov *sriov = &dev->priv.sriov;
bool wait_for_ec_vf_pages = true;
bool wait_for_vf_pages = true;
int err;
int vf;
for (vf = num_vfs - 1; vf >= 0; vf--) {
if (!sriov->vfs_ctx[vf].enabled)
continue;
/* Notify the VF before its disablement to let it clean
* some resources.
*/
blocking_notifier_call_chain(&sriov->vfs_ctx[vf].notifier,
MLX5_PF_NOTIFY_DISABLE_VF, dev);
err = mlx5_core_disable_hca(dev, vf + 1);
if (err) {
mlx5_core_warn(dev, "failed to disable VF %d\n", vf);
continue;
}
sriov->vfs_ctx[vf].enabled = 0;
}
mlx5_eswitch_disable_sriov(dev->priv.eswitch, clear_vf);
/* There are a number of scenarios when SRIOV is being disabled:
* 1. VFs or ECVFs had been created, and now set back to 0 (num_vf_change == true).
* - If EC SRIOV is enabled then this flow is happening on the
* embedded platform, wait for only EC VF pages.
* - If EC SRIOV is not enabled this flow is happening on non-embedded
* platform, wait for the VF pages.
*
* 2. The driver is being unloaded. In this case wait for all pages.
*/
if (num_vf_change) {
if (mlx5_core_ec_sriov_enabled(dev))
wait_for_vf_pages = false;
else
wait_for_ec_vf_pages = false;
}
if (wait_for_ec_vf_pages && mlx5_wait_for_pages(dev, &dev->priv.page_counters[MLX5_EC_VF]))
mlx5_core_warn(dev, "timeout reclaiming EC VFs pages\n");
/* For ECPFs, skip waiting for host VF pages until ECPF is destroyed */
if (mlx5_core_is_ecpf(dev))
return;
if (wait_for_vf_pages && mlx5_wait_for_pages(dev, &dev->priv.page_counters[MLX5_VF]))
mlx5_core_warn(dev, "timeout reclaiming VFs pages\n");
}
static int mlx5_sriov_enable(struct pci_dev *pdev, int num_vfs)
{
struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
struct devlink *devlink = priv_to_devlink(dev);
Annotation
- Immediate include surface: `linux/pci.h`, `linux/mlx5/driver.h`, `linux/mlx5/vport.h`, `mlx5_core.h`, `mlx5_irq.h`, `eswitch.h`.
- Detected declarations: `function Copyright`, `function mlx5_device_enable_sriov`, `function mlx5_device_disable_sriov`, `function mlx5_sriov_enable`, `function mlx5_sriov_disable`, `function mlx5_core_sriov_configure`, `function mlx5_core_sriov_set_msix_vec_count`, `function mlx5_sriov_attach`, `function mlx5_sriov_detach`, `function mlx5_get_max_vfs`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: integration implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.