drm/xe/pm: fix unbalanced ref handling
authorMatthew Auld <matthew.auld@intel.com>
Wed, 22 Feb 2023 12:18:45 +0000 (12:18 +0000)
committerRodrigo Vivi <rodrigo.vivi@intel.com>
Tue, 19 Dec 2023 23:29:08 +0000 (18:29 -0500)
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 <matthew.auld@intel.com>
Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
drivers/gpu/drm/xe/xe_pci.c
drivers/gpu/drm/xe/xe_pm.c
drivers/gpu/drm/xe/xe_pm.h

index 88e28649c4002d0a8631ae4189f552a2d82a0f6d..3474b5c9f1740b2ef76835e5ab9aa9339b73cde3 100644 (file)
@@ -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);
 }
 
index fb0355530e7bdd955e194aa0d1c3e8cdbf617aed..0ef92b746595de2905488556d95fd450778b21bd 100644 (file)
@@ -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;
index b8c5f9558e26379ae048b1927f5476d8d5c967c7..6a885585f65349dfa5591ba9e31c8c80d01edde5 100644 (file)
@@ -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);