drm/xe/xe_pci_error: Group all devres to release them on PCIe slot reset

Add devres grouping to handle device resource cleanup during
PCI error recovery.

Secondary Bus Reset (SBR) is triggered by PCI core when the
error_detected/mmio_enabled callbacks return PCI_ERS_RESULT_NEED_RESET.

Once SBR is complete, the slot_reset callback is triggered. SBR wipes
out all device memory requiring XE KMD to perform a device removal and
reprobe.
Calling xe_pci_remove() alone does not free the devres allocated.
Since there are no exported functions to release all devres, group the
devres allocations and release the entire group during slot reset to
ensure proper cleanup.

Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
Reviewed-by: Mallesh Koujalagi <mallesh.koujalagi@intel.com>
Link: https://patch.msgid.link/20260629082802.3690896-8-riana.tauro@intel.com
Signed-off-by: Riana Tauro <riana.tauro@intel.com>
This commit is contained in:
Riana Tauro 2026-06-29 13:58:04 +05:30
parent 13b9555ffb
commit 0a0fae3327
3 changed files with 12 additions and 0 deletions

View File

@ -495,6 +495,9 @@ struct xe_device {
bool inconsistent_reset;
} wedged;
/** @devres_group: devres group */
void *devres_group;
/** @bo_device: Struct to control async free of BOs */
struct xe_bo_dev {
/** @bo_device.async_free: Free worker */

View File

@ -1078,6 +1078,7 @@ static int xe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
const struct xe_device_desc *desc = (const void *)ent->driver_data;
const struct xe_subplatform_desc *subplatform_desc;
struct xe_device *xe;
void *group;
int err;
subplatform_desc = find_subplatform(desc, pdev->device);
@ -1105,6 +1106,11 @@ static int xe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (xe_display_driver_probe_defer(pdev))
return -EPROBE_DEFER;
/* Group all devres so xe_pci_error_slot_reset() can release them as a unit. */
group = devres_open_group(&pdev->dev, NULL, GFP_KERNEL);
if (!group)
return -ENOMEM;
err = pcim_enable_device(pdev);
if (err)
return err;
@ -1113,6 +1119,8 @@ static int xe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (IS_ERR(xe))
return PTR_ERR(xe);
xe->devres_group = group;
pci_set_drvdata(pdev, &xe->drm);
xe_pm_assert_unbounded_bridge(xe);

View File

@ -89,6 +89,7 @@ static pci_ers_result_t xe_pci_error_slot_reset(struct pci_dev *pdev)
* kernel BOs.
*/
pdev->driver->remove(pdev);
devres_release_group(&pdev->dev, xe->devres_group);
if (pdev->driver->probe(pdev, ent))
return PCI_ERS_RESULT_DISCONNECT;