[PATCH] drm/xe/pf: Restore TotalVFs
Michal Wajdeczko
michal.wajdeczko at intel.com
Mon Jul 15 11:40:52 UTC 2024
If we update TotalVFs to a new value and fail the .probe() then
the PCI subsystem will not restore original value, which might
impact next .probe() attempt. As a backup plan, use managed action
to restore it ourselves.
Signed-off-by: Michal Wajdeczko <michal.wajdeczko at intel.com>
Cc: Piotr Piórkowski <piotr.piorkowski at intel.com>
---
Attempt to fix that at PCI layer is here [1], but until it will be
available for us, we can still fix that on our side.
[1] https://lore.kernel.org/linux-pci/20240715102835.1286-1-michal.wajdeczko@intel.com/
---
drivers/gpu/drm/xe/xe_sriov_pf.c | 48 +++++++++++++++++++++++++++-----
1 file changed, 41 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_sriov_pf.c b/drivers/gpu/drm/xe/xe_sriov_pf.c
index 0f721ae17b26..d61933770f1c 100644
--- a/drivers/gpu/drm/xe/xe_sriov_pf.c
+++ b/drivers/gpu/drm/xe/xe_sriov_pf.c
@@ -17,12 +17,40 @@ static unsigned int wanted_max_vfs(struct xe_device *xe)
return xe_modparam.max_vfs;
}
-static int pf_reduce_totalvfs(struct xe_device *xe, int limit)
+static void restore_totalvfs(void *arg)
+{
+ struct xe_device *xe = arg;
+ struct device *dev = xe->drm.dev;
+ struct pci_dev *pdev = to_pci_dev(dev);
+ int totalvfs = xe->sriov.pf.device_total_vfs;
+
+ xe_sriov_dbg_verbose(xe, "restoring totalvfs to %d\n", totalvfs);
+ pci_sriov_set_totalvfs(pdev, totalvfs);
+}
+
+static int pf_reduce_totalvfs(struct xe_device *xe, u16 limit)
{
struct device *dev = xe->drm.dev;
struct pci_dev *pdev = to_pci_dev(dev);
int err;
+ xe->sriov.pf.device_total_vfs = pci_sriov_get_totalvfs(pdev);
+ xe->sriov.pf.driver_max_vfs = limit;
+
+ xe_sriov_dbg_verbose(xe, "reducing totalvfs from %u to %u\n",
+ xe->sriov.pf.device_total_vfs,
+ xe->sriov.pf.driver_max_vfs);
+
+ /*
+ * XXX: If we update TotalVFs to a new value and fail the .probe()
+ * then the PCI subsystem might not restore original TotalVFs value,
+ * which might impact next .probe() attempt. As a backup plan, use
+ * managed action to restore it ourselves.
+ *
+ * Note that it's not critical if registering that action fails.
+ */
+ devm_add_action(xe->drm.dev, restore_totalvfs, xe);
+
err = pci_sriov_set_totalvfs(pdev, limit);
if (err)
xe_sriov_notice(xe, "Failed to set number of VFs to %d (%pe)\n",
@@ -37,6 +65,14 @@ static bool pf_continue_as_native(struct xe_device *xe, const char *why)
return false;
}
+static bool pf_continue_ready(struct xe_device *xe, u16 max_vfs)
+{
+ xe_assert(xe, max_vfs > 0);
+ xe_sriov_dbg(xe, "preparing for %u VF%s\n", max_vfs, str_plural(max_vfs));
+ pf_reduce_totalvfs(xe, max_vfs);
+ return true;
+}
+
/**
* xe_sriov_pf_readiness - Check if PF functionality can be enabled.
* @xe: the &xe_device to check
@@ -58,18 +94,16 @@ bool xe_sriov_pf_readiness(struct xe_device *xe)
if (!dev_is_pf(dev))
return false;
+ if (!totalvfs)
+ return pf_continue_as_native(xe, "no VFs reported");
+
if (!xe_device_uc_enabled(xe))
return pf_continue_as_native(xe, "Guc submission disabled");
if (!newlimit)
return pf_continue_as_native(xe, "all VFs disabled");
- pf_reduce_totalvfs(xe, newlimit);
-
- xe->sriov.pf.device_total_vfs = totalvfs;
- xe->sriov.pf.driver_max_vfs = newlimit;
-
- return true;
+ return pf_continue_ready(xe, newlimit);
}
/**
--
2.43.0
More information about the Intel-xe
mailing list