mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 13:14:02 +02:00
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:
parent
13b9555ffb
commit
0a0fae3327
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user