[PATCH v3 03/10] drm/xe/xe_pci_error: Group all devres to release them on PCIe slot reset

Riana Tauro
2026-04-02T06:29:47Z

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>
Signed-off-by: Riana Tauro <riana.tauro@intel.com>
---
drivers/gpu/drm/xe/xe_device.c | 7 +++++++
drivers/gpu/drm/xe/xe_device_types.h | 3 +++
drivers/gpu/drm/xe/xe_pci_error.c | 2 ++
3 files changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
index cbce1d0ffe48..d0b29d94edd2 100644
--- a/drivers/gpu/drm/xe/xe_device.c
+++ b/drivers/gpu/drm/xe/xe_device.c
@@ -440,6 +440,7 @@ struct xe_device *xe_device_create(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct xe_device *xe;
+ void *devres_id;
int err;

xe_display_driver_set_hooks(&driver);
@@ -448,10 +449,16 @@ struct xe_device *xe_device_create(struct pci_dev *pdev,
if (err)
return ERR_PTR(err);

+ devres_id = devres_open_group(&pdev->dev, NULL, GFP_KERNEL);
+ if (!devres_id)
+ return ERR_PTR(-ENOMEM);
+
xe = devm_drm_dev_alloc(&pdev->dev, &driver, struct xe_device, drm);
if (IS_ERR(xe))
return xe;

+ xe->devres_group_id = devres_id;
+
err = ttm_device_init(&xe->ttm, &xe_ttm_funcs, xe->drm.dev,
xe->drm.anon_inode->i_mapping,
xe->drm.vma_offset_manager, 0);
diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
index c9fe86b670bd..c89e2d31583c 100644
--- a/drivers/gpu/drm/xe/xe_device_types.h
+++ b/drivers/gpu/drm/xe/xe_device_types.h
@@ -497,6 +497,9 @@ struct xe_device {
/** @in_recovery: Indicates if device is in recovery */
atomic_t in_recovery;

+ /** @devres_group_id: id for devres group */
+ void *devres_group_id;
+
/** @bo_device: Struct to control async free of BOs */
struct xe_bo_dev {
/** @bo_device.async_free: Free worker */
diff --git a/drivers/gpu/drm/xe/xe_pci_error.c b/drivers/gpu/drm/xe/xe_pci_error.c
index cd9f39010278..28b2f4f7c24b 100644
--- a/drivers/gpu/drm/xe/xe_pci_error.c
+++ b/drivers/gpu/drm/xe/xe_pci_error.c
@@ -64,6 +64,7 @@ static pci_ers_result_t xe_pci_error_mmio_enabled(struct pci_dev *pdev)
static pci_ers_result_t xe_pci_error_slot_reset(struct pci_dev *pdev)
{
const struct pci_device_id *ent = pci_match_id(pdev->driver->id_table, pdev);
+ struct xe_device *xe = pdev_to_xe_device(pdev);

dev_err(&pdev->dev, "Xe Pci error recovery: Slot reset\n");

@@ -80,6 +81,7 @@ static pci_ers_result_t xe_pci_error_slot_reset(struct pci_dev *pdev)
* requiring XE KMD to perform a device removal and reprobe.
*/
pdev->driver->remove(pdev);
+ devres_release_group(&pdev->dev, xe->devres_group_id);

if (!pdev->driver->probe(pdev, ent))
return PCI_ERS_RESULT_RECOVERED;
--
2.47.1