All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Imre Deak <imre.deak@intel.com>
Cc: Jani Nikula <jani.nikula@intel.com>, intel-gfx@lists.freedesktop.org
Subject: Re: [Intel-gfx] [PATCH v3 1/9] drm/i915: Allocate power domain set wakerefs dynamically
Date: Thu, 10 Nov 2022 21:11:20 +0200	[thread overview]
Message-ID: <Y21M2J7lu3KdoMtX@intel.com> (raw)
In-Reply-To: <20221108151828.3761358-1-imre.deak@intel.com>

On Tue, Nov 08, 2022 at 05:18:23PM +0200, Imre Deak wrote:
> Since the intel_display_power_domain_set struct, currently its current
> size close to 1kB, can be allocated on the stack, it's better to
> allocate the per-domain wakeref pointer array - used for debugging -
> within the struct dynamically, so do this.
> 
> The memory freeing is guaranteed by the fact that the acquired domain
> references tracked by the struct can't be leaked either.
> 
> v2:
> - Don't use fetch_and_zero() when freeing the wakerefs array. (Jani)
> - Simplify intel_display_power_get/put_in_set(). (Jani)
> - Check in intel_crtc_destroy() that the wakerefs array has been freed.
> v3:
> - Add intel_display_power_set_disabled() and a separate assert
>   function instead of open coding these. (Jani)
> 
> Cc: Jani Nikula <jani.nikula@intel.com>
> Signed-off-by: Imre Deak <imre.deak@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_crtc.c     |  11 ++
>  .../drm/i915/display/intel_display_power.c    | 109 ++++++++++++++----
>  .../drm/i915/display/intel_display_power.h    |   6 +-
>  3 files changed, 104 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c
> index 037fc140b585c..c18d98bfe1a7c 100644
> --- a/drivers/gpu/drm/i915/display/intel_crtc.c
> +++ b/drivers/gpu/drm/i915/display/intel_crtc.c
> @@ -21,6 +21,7 @@
>  #include "intel_crtc.h"
>  #include "intel_cursor.h"
>  #include "intel_display_debugfs.h"
> +#include "intel_display_power.h"
>  #include "intel_display_trace.h"
>  #include "intel_display_types.h"
>  #include "intel_drrs.h"
> @@ -37,6 +38,14 @@ static void assert_vblank_disabled(struct drm_crtc *crtc)
>  		drm_crtc_vblank_put(crtc);
>  }
>  
> +static void assert_power_domains_disabled(struct intel_crtc *crtc)
> +{
> +	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
> +
> +	drm_WARN_ON(&i915->drm,
> +		    !intel_display_power_set_disabled(i915, &crtc->enabled_power_domains));
> +}
> +
>  struct intel_crtc *intel_first_crtc(struct drm_i915_private *i915)
>  {
>  	return to_intel_crtc(drm_crtc_from_index(&i915->drm, 0));
> @@ -204,6 +213,8 @@ static void intel_crtc_destroy(struct drm_crtc *_crtc)
>  
>  	cpu_latency_qos_remove_request(&crtc->vblank_pm_qos);
>  
> +	assert_power_domains_disabled(crtc);
> +
>  	drm_crtc_cleanup(&crtc->base);
>  	kfree(crtc);
>  }
> diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c
> index 4c1de91e56ff9..ca63b4f1af41b 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_power.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_power.c
> @@ -830,20 +830,85 @@ void intel_display_power_put_unchecked(struct drm_i915_private *dev_priv,
>  }
>  #endif
>  
> +#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
> +static void
> +add_domain_to_set(struct drm_i915_private *i915,
> +		  struct intel_display_power_domain_set *power_domain_set,
> +		  enum intel_display_power_domain domain,
> +		  intel_wakeref_t wf)
> +{
> +	drm_WARN_ON(&i915->drm, test_bit(domain, power_domain_set->mask.bits));
> +
> +	if (!power_domain_set->wakerefs)
> +		power_domain_set->wakerefs = kcalloc(POWER_DOMAIN_NUM,
> +						     sizeof(*power_domain_set->wakerefs),
> +						     GFP_KERNEL);
> +
> +	if (power_domain_set->wakerefs)
> +		power_domain_set->wakerefs[domain] = wf;

So if the kcalloc() fails is it going to look like
we're leaking power wakerefs?

> +
> +	set_bit(domain, power_domain_set->mask.bits);
> +}
> +
> +static intel_wakeref_t
> +remove_domain_from_set(struct drm_i915_private *i915,
> +		       struct intel_display_power_domain_set *power_domain_set,
> +		       enum intel_display_power_domain domain)
> +{
> +	intel_wakeref_t wf;
> +
> +	drm_WARN_ON(&i915->drm, !test_bit(domain, power_domain_set->mask.bits));
> +
> +	clear_bit(domain, power_domain_set->mask.bits);
> +
> +	if (!power_domain_set->wakerefs)
> +		return -1;
> +
> +	wf = fetch_and_zero(&power_domain_set->wakerefs[domain]);
> +
> +	if (bitmap_empty(power_domain_set->mask.bits, POWER_DOMAIN_NUM)) {
> +		kfree(power_domain_set->wakerefs);
> +		power_domain_set->wakerefs = NULL;
> +	}
> +
> +	return wf;
> +
> +}
> +#else
> +static void
> +add_domain_to_set(struct drm_i915_private *i915,
> +		  struct intel_display_power_domain_set *power_domain_set,
> +		  enum intel_display_power_domain domain,
> +		  intel_wakeref_t wf)
> +{
> +	drm_WARN_ON(&i915->drm, test_bit(domain, power_domain_set->mask.bits));
> +
> +	set_bit(domain, power_domain_set->mask.bits);
> +}
> +
> +static intel_wakeref_t
> +remove_domain_from_set(struct drm_i915_private *i915,
> +		       struct intel_display_power_domain_set *power_domain_set,
> +		       enum intel_display_power_domain domain)
> +{
> +	drm_WARN_ON(&i915->drm, !test_bit(domain, power_domain_set->mask.bits));
> +
> +	clear_bit(domain, power_domain_set->mask.bits);
> +
> +	return -1;
> +}
> +#endif
> +
>  void
>  intel_display_power_get_in_set(struct drm_i915_private *i915,
>  			       struct intel_display_power_domain_set *power_domain_set,
>  			       enum intel_display_power_domain domain)
>  {
> -	intel_wakeref_t __maybe_unused wf;
> -
> -	drm_WARN_ON(&i915->drm, test_bit(domain, power_domain_set->mask.bits));
> +	intel_wakeref_t wf;
>  
>  	wf = intel_display_power_get(i915, domain);
> -#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
> -	power_domain_set->wakerefs[domain] = wf;
> -#endif
> -	set_bit(domain, power_domain_set->mask.bits);
> +
> +	add_domain_to_set(i915, power_domain_set, domain, wf);
>  }
>  
>  bool
> @@ -853,16 +918,11 @@ intel_display_power_get_in_set_if_enabled(struct drm_i915_private *i915,
>  {
>  	intel_wakeref_t wf;
>  
> -	drm_WARN_ON(&i915->drm, test_bit(domain, power_domain_set->mask.bits));
> -
>  	wf = intel_display_power_get_if_enabled(i915, domain);
>  	if (!wf)
>  		return false;
>  
> -#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
> -	power_domain_set->wakerefs[domain] = wf;
> -#endif
> -	set_bit(domain, power_domain_set->mask.bits);
> +	add_domain_to_set(i915, power_domain_set, domain, wf);
>  
>  	return true;
>  }
> @@ -874,20 +934,27 @@ intel_display_power_put_mask_in_set(struct drm_i915_private *i915,
>  {
>  	enum intel_display_power_domain domain;
>  
> -	drm_WARN_ON(&i915->drm,
> -		    !bitmap_subset(mask->bits, power_domain_set->mask.bits, POWER_DOMAIN_NUM));
> -
>  	for_each_power_domain(domain, mask) {
> -		intel_wakeref_t __maybe_unused wf = -1;
> +		intel_wakeref_t wf = remove_domain_from_set(i915, power_domain_set, domain);
>  
> -#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
> -		wf = fetch_and_zero(&power_domain_set->wakerefs[domain]);
> -#endif
>  		intel_display_power_put(i915, domain, wf);
> -		clear_bit(domain, power_domain_set->mask.bits);
>  	}
>  }
>  
> +bool
> +intel_display_power_set_disabled(struct drm_i915_private *i915,
> +				 struct intel_display_power_domain_set *power_domain_set)
> +{
> +	if (!bitmap_empty(power_domain_set->mask.bits, POWER_DOMAIN_NUM))
> +		return false;
> +
> +#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
> +	drm_WARN_ON(&i915->drm, power_domain_set->wakerefs);
> +#endif
> +
> +	return true;
> +}
> +
>  static int
>  sanitize_disable_power_well_option(const struct drm_i915_private *dev_priv,
>  				   int disable_power_well)
> diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h
> index 1e77e52c87fec..31b0e9ae863c3 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_power.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_power.h
> @@ -147,7 +147,7 @@ struct i915_power_domains {
>  struct intel_display_power_domain_set {
>  	struct intel_power_domain_mask mask;
>  #ifdef CONFIG_DRM_I915_DEBUG_RUNTIME_PM
> -	intel_wakeref_t wakerefs[POWER_DOMAIN_NUM];
> +	intel_wakeref_t *wakerefs;
>  #endif
>  };
>  
> @@ -243,6 +243,10 @@ intel_display_power_put_all_in_set(struct drm_i915_private *i915,
>  	intel_display_power_put_mask_in_set(i915, power_domain_set, &power_domain_set->mask);
>  }
>  
> +bool
> +intel_display_power_set_disabled(struct drm_i915_private *i915,
> +				 struct intel_display_power_domain_set *power_domain_set);
> +
>  void intel_display_power_debug(struct drm_i915_private *i915, struct seq_file *m);
>  
>  enum intel_display_power_domain
> -- 
> 2.37.1

-- 
Ville Syrjälä
Intel

  reply	other threads:[~2022-11-10 19:19 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-07 17:09 [Intel-gfx] [PATCH v2 0/9] drm/i915/tgl+: Enable DC power states on all eDP ports Imre Deak
2022-11-07 17:09 ` [Intel-gfx] [PATCH v2 1/9] drm/i915: Allocate power domain set wakerefs dynamically Imre Deak
2022-11-08  8:54   ` Jani Nikula
2022-11-08 13:45     ` Imre Deak
2022-11-08 15:18   ` [Intel-gfx] [PATCH v3 " Imre Deak
2022-11-10 19:11     ` Ville Syrjälä [this message]
2022-11-10 19:55       ` Imre Deak
2022-11-10 21:49         ` Ville Syrjälä
2022-11-11 12:37           ` Imre Deak
2022-11-11 13:43             ` Ville Syrjälä
2022-11-11 13:52               ` Ville Syrjälä
2022-11-11 15:47                 ` Imre Deak
2022-11-11 18:30                   ` Ville Syrjälä
2022-11-11 18:56                     ` Imre Deak
2022-11-11 19:23                       ` Ville Syrjälä
2022-11-11 21:38                         ` Imre Deak
2022-11-07 17:09 ` [Intel-gfx] [PATCH v2 2/9] drm/i915: Move the POWER_DOMAIN_AUX_IO_A definition to its logical place Imre Deak
2022-11-07 17:09 ` [Intel-gfx] [PATCH v2 3/9] drm/i915: Use the AUX_IO power domain only for eDP/PSR port Imre Deak
2022-11-08 15:18   ` [Intel-gfx] [PATCH v3 " Imre Deak
2022-11-07 17:09 ` [Intel-gfx] [PATCH v2 4/9] drm/i915/tgl+: Enable display DC power states on all eDP ports Imre Deak
2022-11-08 15:18   ` [Intel-gfx] [PATCH v3 " Imre Deak
2022-11-10 18:52     ` Ville Syrjälä
2022-11-10 18:57       ` Ville Syrjälä
2022-11-10 19:10         ` Imre Deak
2022-11-07 17:09 ` [Intel-gfx] [PATCH v2 5/9] drm/i915: Add missing AUX_IO_A power domain->well mappings Imre Deak
2022-11-07 17:09 ` [Intel-gfx] [PATCH v2 6/9] drm/i915: Add missing DC_OFF " Imre Deak
2022-11-07 17:09 ` [Intel-gfx] [PATCH v2 7/9] drm/i915: Factor out function to get/put AUX_IO power for main link Imre Deak
2022-11-08 15:18   ` [Intel-gfx] [PATCH v3 " Imre Deak
2022-11-10 10:21     ` Ville Syrjälä
2022-11-10 10:44       ` Jani Nikula
2022-11-10 12:29       ` Imre Deak
2022-11-07 17:09 ` [Intel-gfx] [PATCH v2 8/9] drm/i915: Don't enable the AUX_IO power for combo-PHY external DP port main links Imre Deak
2022-11-08 15:18   ` [Intel-gfx] [PATCH v3 " Imre Deak
2022-11-10 10:37     ` Ville Syrjälä
2022-11-10 12:27       ` Imre Deak
2022-11-07 17:09 ` [Intel-gfx] [PATCH v2 9/9] drm/i915/mtl+: Don't enable the AUX_IO power for non-eDP " Imre Deak
2022-11-08 15:18   ` [Intel-gfx] [PATCH v3 " Imre Deak
2022-11-07 22:20 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915/tgl+: Enable DC power states on all eDP ports (rev2) Patchwork
2022-11-07 22:20 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2022-11-07 22:39 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2022-11-08  4:18 ` [Intel-gfx] ✗ Fi.CI.IGT: failure " Patchwork
2022-11-08 17:05 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915/tgl+: Enable DC power states on all eDP ports (rev8) Patchwork
2022-11-08 17:05 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2022-11-08 17:27 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2022-11-08 22:52 ` [Intel-gfx] ✓ 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=Y21M2J7lu3KdoMtX@intel.com \
    --to=ville.syrjala@linux.intel.com \
    --cc=imre.deak@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=jani.nikula@intel.com \
    /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.