[Intel-gfx] [PATCH] drm/i915: Do not put big intel_crtc_state on the stack

Jani Nikula jani.nikula at linux.intel.com
Thu Jan 21 01:47:17 PST 2016


On Tue, 19 Jan 2016, Tvrtko Ursulin <tvrtko.ursulin at linux.intel.com> wrote:
> From: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
>
> Having this on stack triggers the -Wframe-larger-than=1024 and
> is not nice to put such big things on the kernel stack anyway.
>
> This required a little bit of refactoring to handle the new
> failure path from vlv_force_pll_on.
>
> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
> Cc: Daniel Vetter <daniel.vetter at ffwll.ch>
> Cc: John Harrison <john.c.harrison at intel.com>
> Cc: Ville Syrjälä <ville.syrjala at linux.intel.com>
> ---
> Compile tested only!
> ---
>  drivers/gpu/drm/i915/intel_display.c | 58 +++++++++++++++++++++++-------------
>  drivers/gpu/drm/i915/intel_dp.c      |  8 +++--
>  drivers/gpu/drm/i915/intel_drv.h     |  4 +--
>  3 files changed, 45 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index ccb3e3f47450..7bf18658c659 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -7635,26 +7635,34 @@ static void chv_prepare_pll(struct intel_crtc *crtc,
>   * in cases where we need the PLL enabled even when @pipe is not going to
>   * be enabled.
>   */
> -void vlv_force_pll_on(struct drm_device *dev, enum pipe pipe,
> +int vlv_force_pll_on(struct drm_device *dev, enum pipe pipe,
>  		      const struct dpll *dpll)
>  {
>  	struct intel_crtc *crtc =
>  		to_intel_crtc(intel_get_crtc_for_pipe(dev, pipe));
> -	struct intel_crtc_state pipe_config = {
> -		.base.crtc = &crtc->base,
> -		.pixel_multiplier = 1,
> -		.dpll = *dpll,
> -	};
> +	struct intel_crtc_state *pipe_config;
> +
> +	pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL);
> +	if (!pipe_config)
> +		return -ENOMEM;
> +
> +	pipe_config->base.crtc = &crtc->base;
> +	pipe_config->pixel_multiplier = 1;
> +	pipe_config->dpll = *dpll;
>  
>  	if (IS_CHERRYVIEW(dev)) {
> -		chv_compute_dpll(crtc, &pipe_config);
> -		chv_prepare_pll(crtc, &pipe_config);
> -		chv_enable_pll(crtc, &pipe_config);
> +		chv_compute_dpll(crtc, pipe_config);
> +		chv_prepare_pll(crtc, pipe_config);
> +		chv_enable_pll(crtc, pipe_config);
>  	} else {
> -		vlv_compute_dpll(crtc, &pipe_config);
> -		vlv_prepare_pll(crtc, &pipe_config);
> -		vlv_enable_pll(crtc, &pipe_config);
> +		vlv_compute_dpll(crtc, pipe_config);
> +		vlv_prepare_pll(crtc, pipe_config);
> +		vlv_enable_pll(crtc, pipe_config);
>  	}
> +
> +	kfree(pipe_config);
> +
> +	return 0;
>  }
>  
>  /**
> @@ -10828,7 +10836,7 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
>  	struct drm_display_mode *mode;
> -	struct intel_crtc_state pipe_config;
> +	struct intel_crtc_state *pipe_config;
>  	int htot = I915_READ(HTOTAL(cpu_transcoder));
>  	int hsync = I915_READ(HSYNC(cpu_transcoder));
>  	int vtot = I915_READ(VTOTAL(cpu_transcoder));
> @@ -10839,6 +10847,12 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
>  	if (!mode)
>  		return NULL;
>  
> +	pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL);

GFP_TEMPORARY

BR,
Jani.

> +	if (!pipe_config) {
> +		kfree(mode);
> +		return NULL;
> +	}
> +
>  	/*
>  	 * Construct a pipe_config sufficient for getting the clock info
>  	 * back out of crtc_clock_get.
> @@ -10846,14 +10860,14 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
>  	 * Note, if LVDS ever uses a non-1 pixel multiplier, we'll need
>  	 * to use a real value here instead.
>  	 */
> -	pipe_config.cpu_transcoder = (enum transcoder) pipe;
> -	pipe_config.pixel_multiplier = 1;
> -	pipe_config.dpll_hw_state.dpll = I915_READ(DPLL(pipe));
> -	pipe_config.dpll_hw_state.fp0 = I915_READ(FP0(pipe));
> -	pipe_config.dpll_hw_state.fp1 = I915_READ(FP1(pipe));
> -	i9xx_crtc_clock_get(intel_crtc, &pipe_config);
> -
> -	mode->clock = pipe_config.port_clock / pipe_config.pixel_multiplier;
> +	pipe_config->cpu_transcoder = (enum transcoder) pipe;
> +	pipe_config->pixel_multiplier = 1;
> +	pipe_config->dpll_hw_state.dpll = I915_READ(DPLL(pipe));
> +	pipe_config->dpll_hw_state.fp0 = I915_READ(FP0(pipe));
> +	pipe_config->dpll_hw_state.fp1 = I915_READ(FP1(pipe));
> +	i9xx_crtc_clock_get(intel_crtc, pipe_config);
> +
> +	mode->clock = pipe_config->port_clock / pipe_config->pixel_multiplier;
>  	mode->hdisplay = (htot & 0xffff) + 1;
>  	mode->htotal = ((htot & 0xffff0000) >> 16) + 1;
>  	mode->hsync_start = (hsync & 0xffff) + 1;
> @@ -10865,6 +10879,8 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
>  
>  	drm_mode_set_name(mode);
>  
> +	kfree(pipe_config);
> +
>  	return mode;
>  }
>  
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 17612548c58d..e2bea710614f 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -335,8 +335,12 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp)
>  		release_cl_override = IS_CHERRYVIEW(dev) &&
>  			!chv_phy_powergate_ch(dev_priv, phy, ch, true);
>  
> -		vlv_force_pll_on(dev, pipe, IS_CHERRYVIEW(dev) ?
> -				 &chv_dpll[0].dpll : &vlv_dpll[0].dpll);
> +		if (vlv_force_pll_on(dev, pipe, IS_CHERRYVIEW(dev) ?
> +				     &chv_dpll[0].dpll : &vlv_dpll[0].dpll)) {
> +			DRM_ERROR("Failed to force on pll for pipe %c!\n",
> +				  pipe_name(pipe));
> +			return;
> +		}
>  	}
>  
>  	/*
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 059b46e22c31..538faaf4eeef 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1177,8 +1177,8 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv,
>  struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,
>  						struct intel_crtc_state *state);
>  
> -void vlv_force_pll_on(struct drm_device *dev, enum pipe pipe,
> -		      const struct dpll *dpll);
> +int vlv_force_pll_on(struct drm_device *dev, enum pipe pipe,
> +		     const struct dpll *dpll);
>  void vlv_force_pll_off(struct drm_device *dev, enum pipe pipe);
>  
>  /* modesetting asserts */

-- 
Jani Nikula, Intel Open Source Technology Center


More information about the Intel-gfx mailing list