All of lore.kernel.org
 help / color / mirror / Atom feed
From: Imre Deak <imre.deak@intel.com>
To: intel-gfx@lists.freedesktop.org
Subject: [PATCH 01/10] drm/i915: Add support for tracking wakerefs w/o power-on guarantee
Date: Fri,  3 May 2019 02:26:39 +0300	[thread overview]
Message-ID: <20190502232648.4450-2-imre.deak@intel.com> (raw)
In-Reply-To: <20190502232648.4450-1-imre.deak@intel.com>

It's useful to track runtime PM refs that don't guarantee a device
power-on state to the rest of the driver. One such case is holding a
reference that will be put asynchronously, during which normal users
without their own reference shouldn't access the HW. A follow-up patch
will add support for disabling display power domains asynchronously
which needs this.

For this we can track all references with a separate wakeref_track_count
and references guaranteeing a power-on state with the current
wakeref_count.

Follow-up patches will make use of the API added here, so add a
__used__ attribute quirk to keep git bisect working.

No functional changes.

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h         |   1 +
 drivers/gpu/drm/i915/intel_runtime_pm.c | 121 ++++++++++++++++++++----
 2 files changed, 102 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 9a634ba57ff9..9fb26634a6be 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1177,6 +1177,7 @@ struct skl_wm_params {
  */
 struct i915_runtime_pm {
 	atomic_t wakeref_count;
+	atomic_t wakeref_track_count;
 	bool suspended;
 	bool irqs_enabled;
 
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 30e7cb9d5801..4a7bfc945322 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -59,6 +59,12 @@
  * present for a given platform.
  */
 
+static void
+assert_raw_rpm_wakelock_held(struct drm_i915_private *i915)
+{
+	WARN_ON(!atomic_read(&i915->runtime_pm.wakeref_track_count));
+}
+
 #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
 
 #include <linux/sort.h>
@@ -100,17 +106,18 @@ static void init_intel_runtime_pm_wakeref(struct drm_i915_private *i915)
 	struct i915_runtime_pm *rpm = &i915->runtime_pm;
 
 	spin_lock_init(&rpm->debug.lock);
+	atomic_set(&rpm->wakeref_track_count, 0);
 }
 
 static noinline depot_stack_handle_t
-track_intel_runtime_pm_wakeref(struct drm_i915_private *i915)
+track_intel_runtime_pm_wakeref_raw(struct drm_i915_private *i915)
 {
 	struct i915_runtime_pm *rpm = &i915->runtime_pm;
 	depot_stack_handle_t stack, *stacks;
 	unsigned long flags;
 
-	atomic_inc(&rpm->wakeref_count);
-	assert_rpm_wakelock_held(i915);
+	atomic_inc(&rpm->wakeref_track_count);
+	assert_raw_rpm_wakelock_held(i915);
 
 	if (!HAS_RUNTIME_PM(i915))
 		return -1;
@@ -139,6 +146,15 @@ track_intel_runtime_pm_wakeref(struct drm_i915_private *i915)
 	return stack;
 }
 
+static noinline depot_stack_handle_t
+track_intel_runtime_pm_wakeref(struct drm_i915_private *i915)
+{
+	atomic_inc(&i915->runtime_pm.wakeref_count);
+	assert_rpm_wakelock_held(i915);
+
+	return track_intel_runtime_pm_wakeref_raw(i915);
+}
+
 static void cancel_intel_runtime_pm_wakeref(struct drm_i915_private *i915,
 					    depot_stack_handle_t stack)
 {
@@ -163,7 +179,7 @@ static void cancel_intel_runtime_pm_wakeref(struct drm_i915_private *i915,
 
 	if (WARN(!found,
 		 "Unmatched wakeref (tracking %lu), count %u\n",
-		 rpm->debug.count, atomic_read(&rpm->wakeref_count))) {
+		 rpm->debug.count, atomic_read(&rpm->wakeref_track_count))) {
 		char *buf;
 
 		buf = kmalloc(PAGE_SIZE, GFP_NOWAIT | __GFP_NOWARN);
@@ -235,15 +251,15 @@ __print_intel_runtime_pm_wakeref(struct drm_printer *p,
 }
 
 static noinline void
-untrack_intel_runtime_pm_wakeref(struct drm_i915_private *i915)
+untrack_intel_runtime_pm_wakeref_raw(struct drm_i915_private *i915)
 {
 	struct i915_runtime_pm *rpm = &i915->runtime_pm;
 	struct intel_runtime_pm_debug dbg = {};
 	struct drm_printer p;
 	unsigned long flags;
 
-	assert_rpm_wakelock_held(i915);
-	if (atomic_dec_and_lock_irqsave(&rpm->wakeref_count,
+	assert_raw_rpm_wakelock_held(i915);
+	if (atomic_dec_and_lock_irqsave(&rpm->wakeref_track_count,
 					&rpm->debug.lock,
 					flags)) {
 		dbg = rpm->debug;
@@ -263,6 +279,15 @@ untrack_intel_runtime_pm_wakeref(struct drm_i915_private *i915)
 	kfree(dbg.owners);
 }
 
+static noinline void
+untrack_intel_runtime_pm_wakeref(struct drm_i915_private *i915)
+{
+	untrack_intel_runtime_pm_wakeref_raw(i915);
+
+	assert_rpm_wakelock_held(i915);
+	atomic_dec(&i915->runtime_pm.wakeref_count);
+}
+
 void print_intel_runtime_pm_wakeref(struct drm_i915_private *i915,
 				    struct drm_printer *p)
 {
@@ -308,15 +333,33 @@ static void init_intel_runtime_pm_wakeref(struct drm_i915_private *i915)
 }
 
 static depot_stack_handle_t
-track_intel_runtime_pm_wakeref(struct drm_i915_private *i915)
+track_intel_runtime_pm_wakeref_raw(struct drm_i915_private *i915)
 {
-	atomic_inc(&i915->runtime_pm.wakeref_count);
-	assert_rpm_wakelock_held(i915);
+	atomic_inc(&i915->runtime_pm.wakeref_track_count);
+	assert_raw_rpm_wakelock_held(i915);
+
 	return -1;
 }
 
+static depot_stack_handle_t
+track_intel_runtime_pm_wakeref(struct drm_i915_private *i915)
+{
+	atomic_inc(&i915->runtime_pm.wakeref_count);
+	assert_rpm_wakelock_held(i915);
+
+	return track_intel_runtime_pm_wakeref_raw(i915);
+}
+
+static void untrack_intel_runtime_pm_wakeref_raw(struct drm_i915_private *i915)
+{
+	assert_raw_rpm_wakelock_held(i915);
+	atomic_dec(&i915->runtime_pm.wakeref_track_count);
+}
+
 static void untrack_intel_runtime_pm_wakeref(struct drm_i915_private *i915)
 {
+	untrack_intel_runtime_pm_wakeref_raw(i915);
+
 	assert_rpm_wakelock_held(i915);
 	atomic_dec(&i915->runtime_pm.wakeref_count);
 }
@@ -4347,7 +4390,7 @@ static void intel_power_domains_verify_state(struct drm_i915_private *i915)
  *
  * Returns: the wakeref cookie to pass to intel_runtime_pm_put()
  */
-intel_wakeref_t intel_runtime_pm_get(struct drm_i915_private *i915)
+static void __intel_runtime_pm_get(struct drm_i915_private *i915)
 {
 	struct pci_dev *pdev = i915->drm.pdev;
 	struct device *kdev = &pdev->dev;
@@ -4355,6 +4398,19 @@ intel_wakeref_t intel_runtime_pm_get(struct drm_i915_private *i915)
 
 	ret = pm_runtime_get_sync(kdev);
 	WARN_ONCE(ret < 0, "pm_runtime_get_sync() failed: %d\n", ret);
+}
+
+__attribute__((__used__))
+static intel_wakeref_t intel_runtime_pm_get_raw(struct drm_i915_private *i915)
+{
+	__intel_runtime_pm_get(i915);
+
+	return track_intel_runtime_pm_wakeref_raw(i915);
+}
+
+intel_wakeref_t intel_runtime_pm_get(struct drm_i915_private *i915)
+{
+	__intel_runtime_pm_get(i915);
 
 	return track_intel_runtime_pm_wakeref(i915);
 }
@@ -4430,23 +4486,48 @@ intel_wakeref_t intel_runtime_pm_get_noresume(struct drm_i915_private *i915)
  * intel_runtime_pm_get() and might power down the corresponding
  * hardware block right away if this is the last reference.
  */
+static void __intel_runtime_pm_put_unchecked(struct drm_i915_private *i915)
+{
+	struct pci_dev *pdev = i915->drm.pdev;
+	struct device *kdev = &pdev->dev;
+
+	pm_runtime_mark_last_busy(kdev);
+	pm_runtime_put_autosuspend(kdev);
+}
+
+static void intel_runtime_pm_put_unchecked_raw(struct drm_i915_private *i915)
+{
+	untrack_intel_runtime_pm_wakeref_raw(i915);
+	__intel_runtime_pm_put_unchecked(i915);
+}
+
 void intel_runtime_pm_put_unchecked(struct drm_i915_private *i915)
 {
-	struct pci_dev *pdev = i915->drm.pdev;
-	struct device *kdev = &pdev->dev;
-
 	untrack_intel_runtime_pm_wakeref(i915);
-
-	pm_runtime_mark_last_busy(kdev);
-	pm_runtime_put_autosuspend(kdev);
+	__intel_runtime_pm_put_unchecked(i915);
 }
 
 #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
+__attribute__((__used__))
+static void intel_runtime_pm_put_raw(struct drm_i915_private *i915,
+				     intel_wakeref_t wref)
+{
+	cancel_intel_runtime_pm_wakeref(i915, wref);
+	intel_runtime_pm_put_unchecked_raw(i915);
+}
+
 void intel_runtime_pm_put(struct drm_i915_private *i915, intel_wakeref_t wref)
 {
 	cancel_intel_runtime_pm_wakeref(i915, wref);
 	intel_runtime_pm_put_unchecked(i915);
 }
+#else
+__attribute__((__used__))
+static void intel_runtime_pm_put_raw(struct drm_i915_private *i915,
+				     intel_wakeref_t wref)
+{
+	intel_runtime_pm_put_unchecked_raw(i915);
+}
 #endif
 
 /**
@@ -4521,12 +4602,12 @@ void intel_runtime_pm_cleanup(struct drm_i915_private *i915)
 	struct i915_runtime_pm *rpm = &i915->runtime_pm;
 	int count;
 
-	count = atomic_fetch_inc(&rpm->wakeref_count); /* balance untrack */
+	count = atomic_fetch_inc(&rpm->wakeref_track_count); /* balance untrack */
 	WARN(count,
-	     "i915->runtime_pm.wakeref_count=%d on cleanup\n",
+	     "i915->runtime_pm.wakeref_track_count=%d on cleanup\n",
 	     count);
 
-	untrack_intel_runtime_pm_wakeref(i915);
+	untrack_intel_runtime_pm_wakeref_raw(i915);
 }
 
 void intel_runtime_pm_init_early(struct drm_i915_private *i915)
-- 
2.17.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2019-05-02 23:27 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-02 23:26 [PATCH 00/10] drm/i915: Add support for asynchronous display power disabling Imre Deak
2019-05-02 23:26 ` Imre Deak [this message]
2019-05-07 14:03   ` [PATCH 01/10] drm/i915: Add support for tracking wakerefs w/o power-on guarantee Chris Wilson
2019-05-02 23:26 ` [PATCH 02/10] drm/i915: Verify power domains state during suspend in all cases Imre Deak
2019-05-02 23:26 ` [PATCH 03/10] drm/i915: Add support for asynchronous display power disabling Imre Deak
2019-05-03 12:16   ` Chris Wilson
2019-05-03 13:42     ` Imre Deak
2019-05-06 11:12   ` [PATCH v2 " Imre Deak
2019-05-02 23:26 ` [PATCH 04/10] drm/i915: Disable power asynchronously during DP AUX transfers Imre Deak
2019-05-02 23:26 ` [PATCH 05/10] drm/i915: WARN for eDP encoders in intel_dp_detect_dpcd() Imre Deak
2019-05-02 23:26 ` [PATCH 06/10] drm/i915: Remove the unneeded AUX power ref from intel_dp_detect() Imre Deak
2019-05-02 23:26 ` [PATCH 07/10] drm/i915: Remove the unneeded AUX power ref from intel_dp_hpd_pulse() Imre Deak
2019-05-02 23:26 ` [PATCH 08/10] drm/i915: Replace use of PLLS power domain with DISPLAY_CORE domain Imre Deak
2019-05-02 23:26 ` [PATCH 09/10] drm/i915: Avoid taking the PPS lock for non-eDP/VLV/CHV Imre Deak
2019-05-06 12:35   ` Ville Syrjälä
2019-05-06 13:12     ` Ville Syrjälä
2019-05-06 13:15       ` Imre Deak
2019-05-02 23:26 ` [PATCH 10/10] drm/i915: Assert that TypeC ports are not used for eDP Imre Deak
2019-05-03  0:34 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Add support for asynchronous display power disabling Patchwork
2019-05-03  0:38 ` ✗ Fi.CI.SPARSE: " Patchwork
2019-05-03  1:12 ` ✓ Fi.CI.BAT: success " Patchwork
2019-05-03  7:50 ` ✗ Fi.CI.IGT: failure " Patchwork
2019-05-03 10:07   ` Imre Deak
2019-05-03 12:37     ` Chris Wilson
2019-05-03 13:52       ` Imre Deak
2019-05-03 14:21         ` Imre Deak
2019-05-06  9:44         ` Imre Deak
2019-05-06 11:29 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Add support for asynchronous display power disabling (rev2) Patchwork
2019-05-06 11:49 ` ✓ Fi.CI.BAT: success " Patchwork
2019-05-06 12:57 ` ✓ Fi.CI.IGT: " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190502232648.4450-2-imre.deak@intel.com \
    --to=imre.deak@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.