From 5b7e50e2ea1745bd09c3d99a4f7c49d630124825 Mon Sep 17 00:00:00 2001 From: Matthew Auld Date: Wed, 22 Feb 2023 12:18:45 +0000 Subject: [PATCH] drm/xe/pm: fix unbalanced ref handling In local_pci_probe() the core kernel increments the rpm for the device, just before calling into the probe hook. If the driver/device supports runtime pm it is then meant to put this ref during probe (like we do in xe_pm_runtime_init()). However when removing the device we then also need to take the reference back, otherwise the ref that is put in pci_device_remove() will be unbalanced when for example unloading the driver, leading to warnings like: [ 3808.596345] xe 0000:03:00.0: Runtime PM usage count underflow! Fix this by incrementing the rpm ref when removing the device. v2: - Improve the terminology in the commit message; s/drop/put/ etc (Lucas & Rodrigo) - Also call pm_runtime_forbid(dev) (Rodrigo) Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/193 Signed-off-by: Matthew Auld Cc: Lucas De Marchi Cc: Rodrigo Vivi Reviewed-by: Rodrigo Vivi Reviewed-by: Lucas De Marchi Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/xe/xe_pci.c | 1 + drivers/gpu/drm/xe/xe_pm.c | 8 ++++++++ drivers/gpu/drm/xe/xe_pm.h | 1 + 3 files changed, 10 insertions(+) diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c index 88e28649c400..3474b5c9f174 100644 --- a/drivers/gpu/drm/xe/xe_pci.c +++ b/drivers/gpu/drm/xe/xe_pci.c @@ -364,6 +364,7 @@ static void xe_pci_remove(struct pci_dev *pdev) return; xe_device_remove(xe); + xe_pm_runtime_fini(xe); pci_set_drvdata(pdev, NULL); } diff --git a/drivers/gpu/drm/xe/xe_pm.c b/drivers/gpu/drm/xe/xe_pm.c index fb0355530e7b..0ef92b746595 100644 --- a/drivers/gpu/drm/xe/xe_pm.c +++ b/drivers/gpu/drm/xe/xe_pm.c @@ -117,6 +117,14 @@ void xe_pm_runtime_init(struct xe_device *xe) pm_runtime_put_autosuspend(dev); } +void xe_pm_runtime_fini(struct xe_device *xe) +{ + struct device *dev = xe->drm.dev; + + pm_runtime_get_sync(dev); + pm_runtime_forbid(dev); +} + int xe_pm_runtime_suspend(struct xe_device *xe) { struct xe_gt *gt; diff --git a/drivers/gpu/drm/xe/xe_pm.h b/drivers/gpu/drm/xe/xe_pm.h index b8c5f9558e26..6a885585f653 100644 --- a/drivers/gpu/drm/xe/xe_pm.h +++ b/drivers/gpu/drm/xe/xe_pm.h @@ -14,6 +14,7 @@ int xe_pm_suspend(struct xe_device *xe); int xe_pm_resume(struct xe_device *xe); void xe_pm_runtime_init(struct xe_device *xe); +void xe_pm_runtime_fini(struct xe_device *xe); int xe_pm_runtime_suspend(struct xe_device *xe); int xe_pm_runtime_resume(struct xe_device *xe); int xe_pm_runtime_get(struct xe_device *xe);