All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Jani Nikula <jani.nikula@intel.com>
Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
Subject: Re: [Intel-gfx] [PATCH v7 17/22] drm/edid: add separate drm_edid_connector_add_modes()
Date: Thu, 19 Jan 2023 14:23:10 +0200	[thread overview]
Message-ID: <Y8k2LmANifrnijbV@intel.com> (raw)
In-Reply-To: <c1b49ee5e13fb4b4cdb8db42122b71814c5b42bb.1672826282.git.jani.nikula@intel.com>

On Wed, Jan 04, 2023 at 12:05:32PM +0200, Jani Nikula wrote:
> The original goal with drm_edid_connector_update() was to have a single
> call for updating the connector and adding probed modes, in this order,
> but that turned out to be problematic. Drivers that need to update the
> connector in the .detect() callback would end up updating the probed
> modes as well. Turns out the callback may be called so many times that
> the probed mode list fills up without bounds, and this is amplified by
> add_alternate_cea_modes() duplicating the CEA modes on every call,
> actually running out of memory on some machines.
> 
> Kudos to Imre Deak <imre.deak@intel.com> for explaining this to me.
> 
> Go back to having separate drm_edid_connector_update() and
> drm_edid_connector_add_modes() calls. The former may be called from
> .detect(), .force(), or .get_modes(), but the latter only from
> .get_modes().
> 
> Unlike drm_add_edid_modes(), have drm_edid_connector_add_modes() update
> the probed modes from the EDID property instead of the passed in
> EDID. This is mainly to enforce two things:
> 
> 1) drm_edid_connector_update() must be called before
>    drm_edid_connector_add_modes().
> 
>    Display info and quirks are needed for parsing the modes, and we
>    don't want to call update_display_info() again to ensure the info is
>    available, like drm_add_edid_modes() does.
> 
> 2) The same EDID is used for both updating the connector and adding the
>    probed modes.
> 
> Fortunately, the change is easy, because no driver has actually adopted
> drm_edid_connector_update(). Not even i915, and that's mainly because of
> the problem described above.
> 
> Cc: Imre Deak <imre.deak@intel.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/drm_edid.c         | 44 +++++++++++++++++++++++-------
>  drivers/gpu/drm/drm_probe_helper.c |  4 ++-
>  include/drm/drm_edid.h             |  2 ++
>  3 files changed, 39 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 95c383220afc..a64c0807e97f 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -6761,30 +6761,54 @@ static int _drm_edid_connector_property_update(struct drm_connector *connector,
>   * @connector: Connector
>   * @drm_edid: EDID
>   *
> - * Update the connector mode list, display info, ELD, HDR metadata, relevant
> - * properties, etc. from the passed in EDID.
> + * Update the connector display info, ELD, HDR metadata, relevant properties,
> + * etc. from the passed in EDID.
>   *
>   * If EDID is NULL, reset the information.
>   *
> - * Return: The number of modes added or 0 if we couldn't find any.
> + * Must be called before calling drm_edid_connector_add_modes().
> + *
> + * Return: 0 on success, negative error on errors.
>   */
>  int drm_edid_connector_update(struct drm_connector *connector,
>  			      const struct drm_edid *drm_edid)
>  {
> +	update_display_info(connector, drm_edid);
> +
> +	_drm_update_tile_info(connector, drm_edid);
> +
> +	return _drm_edid_connector_property_update(connector, drm_edid);
> +}
> +EXPORT_SYMBOL(drm_edid_connector_update);
> +
> +/**
> + * drm_edid_connector_add_modes - Update probed modes from the EDID property
> + * @connector: Connector
> + *
> + * Add the modes from the previously updated EDID property to the connector
> + * probed modes list.
> + *
> + * drm_edid_connector_update() must have been called before this to update the
> + * EDID property.
> + *
> + * Return: The number of modes added, or 0 if we couldn't find any.
> + */
> +int drm_edid_connector_add_modes(struct drm_connector *connector)
> +{
> +	const struct drm_edid *drm_edid = NULL;
>  	int count;
>  
> -	update_display_info(connector, drm_edid);
> +	if (connector->edid_blob_ptr)
> +		drm_edid = drm_edid_alloc(connector->edid_blob_ptr->data,
> +					  connector->edid_blob_ptr->length);
>  
>  	count = _drm_edid_connector_add_modes(connector, drm_edid);
>  
> -	_drm_update_tile_info(connector, drm_edid);
> -
> -	/* Note: Ignore errors for now. */
> -	_drm_edid_connector_property_update(connector, drm_edid);
> +	drm_edid_free(drm_edid);
>  
>  	return count;
>  }
> -EXPORT_SYMBOL(drm_edid_connector_update);
> +EXPORT_SYMBOL(drm_edid_connector_add_modes);
>  
>  static int _drm_connector_update_edid_property(struct drm_connector *connector,
>  					       const struct drm_edid *drm_edid)
> @@ -6839,7 +6863,7 @@ EXPORT_SYMBOL(drm_connector_update_edid_property);
>   * &drm_display_info structure and ELD in @connector with any information which
>   * can be derived from the edid.
>   *
> - * This function is deprecated. Use drm_edid_connector_update() instead.
> + * This function is deprecated. Use drm_edid_connector_add_modes() instead.
>   *
>   * Return: The number of modes added or 0 if we couldn't find any.
>   */
> diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
> index 1ea053cef557..26844befc6f5 100644
> --- a/drivers/gpu/drm/drm_probe_helper.c
> +++ b/drivers/gpu/drm/drm_probe_helper.c
> @@ -1139,7 +1139,9 @@ int drm_connector_helper_get_modes(struct drm_connector *connector)
>  	 * EDID. Otherwise, if the EDID is NULL, clear the connector
>  	 * information.
>  	 */
> -	count = drm_edid_connector_update(connector, drm_edid);
> +	drm_edid_connector_update(connector, drm_edid);
> +
> +	count = drm_edid_connector_add_modes(connector);
>  
>  	drm_edid_free(drm_edid);
>  
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index 372963600f1d..70ae6c290bdc 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -609,6 +609,8 @@ const struct drm_edid *drm_edid_read_custom(struct drm_connector *connector,
>  					    void *context);
>  int drm_edid_connector_update(struct drm_connector *connector,
>  			      const struct drm_edid *edid);
> +int drm_edid_connector_add_modes(struct drm_connector *connector);
> +
>  const u8 *drm_find_edid_extension(const struct drm_edid *drm_edid,
>  				  int ext_id, int *ext_index);
>  
> -- 
> 2.34.1

-- 
Ville Syrjälä
Intel

WARNING: multiple messages have this Message-ID (diff)
From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Jani Nikula <jani.nikula@intel.com>
Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
Subject: Re: [PATCH v7 17/22] drm/edid: add separate drm_edid_connector_add_modes()
Date: Thu, 19 Jan 2023 14:23:10 +0200	[thread overview]
Message-ID: <Y8k2LmANifrnijbV@intel.com> (raw)
In-Reply-To: <c1b49ee5e13fb4b4cdb8db42122b71814c5b42bb.1672826282.git.jani.nikula@intel.com>

On Wed, Jan 04, 2023 at 12:05:32PM +0200, Jani Nikula wrote:
> The original goal with drm_edid_connector_update() was to have a single
> call for updating the connector and adding probed modes, in this order,
> but that turned out to be problematic. Drivers that need to update the
> connector in the .detect() callback would end up updating the probed
> modes as well. Turns out the callback may be called so many times that
> the probed mode list fills up without bounds, and this is amplified by
> add_alternate_cea_modes() duplicating the CEA modes on every call,
> actually running out of memory on some machines.
> 
> Kudos to Imre Deak <imre.deak@intel.com> for explaining this to me.
> 
> Go back to having separate drm_edid_connector_update() and
> drm_edid_connector_add_modes() calls. The former may be called from
> .detect(), .force(), or .get_modes(), but the latter only from
> .get_modes().
> 
> Unlike drm_add_edid_modes(), have drm_edid_connector_add_modes() update
> the probed modes from the EDID property instead of the passed in
> EDID. This is mainly to enforce two things:
> 
> 1) drm_edid_connector_update() must be called before
>    drm_edid_connector_add_modes().
> 
>    Display info and quirks are needed for parsing the modes, and we
>    don't want to call update_display_info() again to ensure the info is
>    available, like drm_add_edid_modes() does.
> 
> 2) The same EDID is used for both updating the connector and adding the
>    probed modes.
> 
> Fortunately, the change is easy, because no driver has actually adopted
> drm_edid_connector_update(). Not even i915, and that's mainly because of
> the problem described above.
> 
> Cc: Imre Deak <imre.deak@intel.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/drm_edid.c         | 44 +++++++++++++++++++++++-------
>  drivers/gpu/drm/drm_probe_helper.c |  4 ++-
>  include/drm/drm_edid.h             |  2 ++
>  3 files changed, 39 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 95c383220afc..a64c0807e97f 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -6761,30 +6761,54 @@ static int _drm_edid_connector_property_update(struct drm_connector *connector,
>   * @connector: Connector
>   * @drm_edid: EDID
>   *
> - * Update the connector mode list, display info, ELD, HDR metadata, relevant
> - * properties, etc. from the passed in EDID.
> + * Update the connector display info, ELD, HDR metadata, relevant properties,
> + * etc. from the passed in EDID.
>   *
>   * If EDID is NULL, reset the information.
>   *
> - * Return: The number of modes added or 0 if we couldn't find any.
> + * Must be called before calling drm_edid_connector_add_modes().
> + *
> + * Return: 0 on success, negative error on errors.
>   */
>  int drm_edid_connector_update(struct drm_connector *connector,
>  			      const struct drm_edid *drm_edid)
>  {
> +	update_display_info(connector, drm_edid);
> +
> +	_drm_update_tile_info(connector, drm_edid);
> +
> +	return _drm_edid_connector_property_update(connector, drm_edid);
> +}
> +EXPORT_SYMBOL(drm_edid_connector_update);
> +
> +/**
> + * drm_edid_connector_add_modes - Update probed modes from the EDID property
> + * @connector: Connector
> + *
> + * Add the modes from the previously updated EDID property to the connector
> + * probed modes list.
> + *
> + * drm_edid_connector_update() must have been called before this to update the
> + * EDID property.
> + *
> + * Return: The number of modes added, or 0 if we couldn't find any.
> + */
> +int drm_edid_connector_add_modes(struct drm_connector *connector)
> +{
> +	const struct drm_edid *drm_edid = NULL;
>  	int count;
>  
> -	update_display_info(connector, drm_edid);
> +	if (connector->edid_blob_ptr)
> +		drm_edid = drm_edid_alloc(connector->edid_blob_ptr->data,
> +					  connector->edid_blob_ptr->length);
>  
>  	count = _drm_edid_connector_add_modes(connector, drm_edid);
>  
> -	_drm_update_tile_info(connector, drm_edid);
> -
> -	/* Note: Ignore errors for now. */
> -	_drm_edid_connector_property_update(connector, drm_edid);
> +	drm_edid_free(drm_edid);
>  
>  	return count;
>  }
> -EXPORT_SYMBOL(drm_edid_connector_update);
> +EXPORT_SYMBOL(drm_edid_connector_add_modes);
>  
>  static int _drm_connector_update_edid_property(struct drm_connector *connector,
>  					       const struct drm_edid *drm_edid)
> @@ -6839,7 +6863,7 @@ EXPORT_SYMBOL(drm_connector_update_edid_property);
>   * &drm_display_info structure and ELD in @connector with any information which
>   * can be derived from the edid.
>   *
> - * This function is deprecated. Use drm_edid_connector_update() instead.
> + * This function is deprecated. Use drm_edid_connector_add_modes() instead.
>   *
>   * Return: The number of modes added or 0 if we couldn't find any.
>   */
> diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
> index 1ea053cef557..26844befc6f5 100644
> --- a/drivers/gpu/drm/drm_probe_helper.c
> +++ b/drivers/gpu/drm/drm_probe_helper.c
> @@ -1139,7 +1139,9 @@ int drm_connector_helper_get_modes(struct drm_connector *connector)
>  	 * EDID. Otherwise, if the EDID is NULL, clear the connector
>  	 * information.
>  	 */
> -	count = drm_edid_connector_update(connector, drm_edid);
> +	drm_edid_connector_update(connector, drm_edid);
> +
> +	count = drm_edid_connector_add_modes(connector);
>  
>  	drm_edid_free(drm_edid);
>  
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index 372963600f1d..70ae6c290bdc 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -609,6 +609,8 @@ const struct drm_edid *drm_edid_read_custom(struct drm_connector *connector,
>  					    void *context);
>  int drm_edid_connector_update(struct drm_connector *connector,
>  			      const struct drm_edid *edid);
> +int drm_edid_connector_add_modes(struct drm_connector *connector);
> +
>  const u8 *drm_find_edid_extension(const struct drm_edid *drm_edid,
>  				  int ext_id, int *ext_index);
>  
> -- 
> 2.34.1

-- 
Ville Syrjälä
Intel

  reply	other threads:[~2023-01-19 12:23 UTC|newest]

Thread overview: 97+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-04 10:05 [Intel-gfx] [PATCH v7 00/22] drm/edid: info & modes parsing and drm_edid refactors Jani Nikula
2023-01-04 10:05 ` Jani Nikula
2023-01-04 10:05 ` [Intel-gfx] [PATCH v7 01/22] drm/edid: fix AVI infoframe aspect ratio handling Jani Nikula
2023-01-04 10:05   ` Jani Nikula
2023-01-04 10:05   ` Jani Nikula
2023-01-18 14:56   ` [Intel-gfx] " Ville Syrjälä
2023-01-18 14:56     ` Ville Syrjälä
2023-01-18 14:56     ` Ville Syrjälä
2023-01-04 10:05 ` [Intel-gfx] [PATCH v7 02/22] drm/edid: fix parsing of 3D modes from HDMI VSDB Jani Nikula
2023-01-04 10:05   ` Jani Nikula
2023-01-04 10:05   ` Jani Nikula
2023-01-18 15:00   ` [Intel-gfx] " Ville Syrjälä
2023-01-18 15:00     ` Ville Syrjälä
2023-01-18 15:00     ` Ville Syrjälä
2023-01-04 10:05 ` [Intel-gfx] [PATCH v7 03/22] drm/edid: parse VICs from CTA VDB early Jani Nikula
2023-01-04 10:05   ` Jani Nikula
2023-01-18 15:12   ` [Intel-gfx] " Ville Syrjälä
2023-01-18 15:12     ` Ville Syrjälä
2023-01-04 10:05 ` [Intel-gfx] [PATCH v7 04/22] drm/edid: Use the pre-parsed VICs Jani Nikula
2023-01-04 10:05   ` Jani Nikula
2023-01-18 15:08   ` [Intel-gfx] " Ville Syrjälä
2023-01-18 15:08     ` Ville Syrjälä
2023-01-04 10:05 ` [Intel-gfx] [PATCH v7 05/22] drm/edid: use VIC in AVI infoframe if sink lists it in CTA VDB Jani Nikula
2023-01-04 10:05   ` Jani Nikula
2023-01-18 15:18   ` [Intel-gfx] " Ville Syrjälä
2023-01-18 15:18     ` Ville Syrjälä
2023-01-04 10:05 ` [Intel-gfx] [PATCH v7 06/22] drm/edid: rename struct drm_display_info *display to *info Jani Nikula
2023-01-04 10:05   ` Jani Nikula
2023-01-18 15:19   ` [Intel-gfx] " Ville Syrjälä
2023-01-18 15:19     ` Ville Syrjälä
2023-01-04 10:05 ` [Intel-gfx] [PATCH v7 07/22] drm/edid: refactor CTA Y420CMDB parsing Jani Nikula
2023-01-04 10:05   ` Jani Nikula
2023-01-18 15:24   ` [Intel-gfx] " Ville Syrjälä
2023-01-18 15:24     ` Ville Syrjälä
2023-01-04 10:05 ` [Intel-gfx] [PATCH v7 08/22] drm/edid: split CTA Y420VDB info and mode parsing Jani Nikula
2023-01-04 10:05   ` Jani Nikula
2023-01-18 15:32   ` [Intel-gfx] " Ville Syrjälä
2023-01-18 15:32     ` Ville Syrjälä
2023-01-04 10:05 ` [Intel-gfx] [PATCH v7 09/22] drm/edid: fix and clarify HDMI VSDB audio latency parsing Jani Nikula
2023-01-04 10:05   ` Jani Nikula
2023-01-18 15:41   ` [Intel-gfx] " Ville Syrjälä
2023-01-18 15:41     ` Ville Syrjälä
2023-01-04 10:05 ` [Intel-gfx] [PATCH v7 10/22] drm/edid: add helper for HDMI VSDB audio latency field length Jani Nikula
2023-01-04 10:05   ` Jani Nikula
2023-01-18 15:42   ` [Intel-gfx] " Ville Syrjälä
2023-01-18 15:42     ` Ville Syrjälä
2023-01-19  9:44     ` [Intel-gfx] " Jani Nikula
2023-01-19  9:44       ` Jani Nikula
2023-01-04 10:05 ` [Intel-gfx] [PATCH v7 11/22] drm/edid: split HDMI VSDB info and mode parsing Jani Nikula
2023-01-04 10:05   ` Jani Nikula
2023-01-18 16:08   ` [Intel-gfx] " Ville Syrjälä
2023-01-18 16:08     ` Ville Syrjälä
2023-01-19 15:46   ` [Intel-gfx] [PATCH] " Jani Nikula
2023-01-19 15:46     ` Jani Nikula
2023-01-19 15:59     ` [Intel-gfx] " Ville Syrjälä
2023-01-19 15:59       ` Ville Syrjälä
2023-01-04 10:05 ` [Intel-gfx] [PATCH v7 12/22] drm/edid: store quirks in display info Jani Nikula
2023-01-04 10:05   ` Jani Nikula
2023-01-18 16:09   ` [Intel-gfx] " Ville Syrjälä
2023-01-18 16:09     ` Ville Syrjälä
2023-01-04 10:05 ` [Intel-gfx] [PATCH v7 13/22] drm/edid: stop passing quirks around Jani Nikula
2023-01-04 10:05   ` Jani Nikula
2023-01-18 16:09   ` [Intel-gfx] " Ville Syrjälä
2023-01-18 16:09     ` Ville Syrjälä
2023-01-04 10:05 ` [Intel-gfx] [PATCH v7 14/22] drm/edid: merge ELD handling to update_display_info() Jani Nikula
2023-01-04 10:05   ` Jani Nikula
2023-01-18 16:14   ` [Intel-gfx] " Ville Syrjälä
2023-01-18 16:14     ` Ville Syrjälä
2023-01-04 10:05 ` [Intel-gfx] [PATCH v7 15/22] drm/edid: move EDID BPC quirk application " Jani Nikula
2023-01-04 10:05   ` Jani Nikula
2023-01-18 16:15   ` [Intel-gfx] " Ville Syrjälä
2023-01-18 16:15     ` Ville Syrjälä
2023-01-19 12:16     ` [Intel-gfx] " Jani Nikula
2023-01-19 12:16       ` Jani Nikula
2023-01-04 10:05 ` [Intel-gfx] [PATCH v7 16/22] drm/edid: refactor _drm_edid_connector_update() and rename Jani Nikula
2023-01-04 10:05   ` Jani Nikula
2023-01-19 12:19   ` [Intel-gfx] " Ville Syrjälä
2023-01-19 12:19     ` Ville Syrjälä
2023-01-04 10:05 ` [Intel-gfx] [PATCH v7 17/22] drm/edid: add separate drm_edid_connector_add_modes() Jani Nikula
2023-01-04 10:05   ` Jani Nikula
2023-01-19 12:23   ` Ville Syrjälä [this message]
2023-01-19 12:23     ` Ville Syrjälä
2023-01-04 10:05 ` [Intel-gfx] [PATCH v7 18/22] drm/edid: remove redundant _drm_connector_update_edid_property() Jani Nikula
2023-01-04 10:05   ` Jani Nikula
2023-01-19 12:23   ` [Intel-gfx] " Ville Syrjälä
2023-01-19 12:23     ` Ville Syrjälä
2023-01-04 10:05 ` [Intel-gfx] [PATCH v7 19/22] drm/i915/edid: convert DP, HDMI and LVDS to drm_edid Jani Nikula
2023-01-04 10:05   ` Jani Nikula
2023-01-04 10:05 ` [Intel-gfx] [PATCH v7 20/22] drm/i915/bios: convert intel_bios_init_panel() " Jani Nikula
2023-01-04 10:05   ` Jani Nikula
2023-01-04 10:05 ` [Intel-gfx] [PATCH v7 21/22] drm/i915/opregion: convert intel_opregion_get_edid() to struct drm_edid Jani Nikula
2023-01-04 10:05   ` Jani Nikula
2023-01-04 10:05 ` [Intel-gfx] [PATCH v7 22/22] drm/i915/panel: move panel fixed EDID to struct intel_panel Jani Nikula
2023-01-04 10:05   ` Jani Nikula
2023-01-04 10:20 ` [Intel-gfx] ✗ Fi.CI.SPARSE: warning for drm/edid: info & modes parsing and drm_edid refactors Patchwork
2023-01-04 10:40 ` [Intel-gfx] ✗ Fi.CI.BAT: failure " Patchwork
2023-01-19 15:49 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for drm/edid: info & modes parsing and drm_edid refactors (rev2) 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=Y8k2LmANifrnijbV@intel.com \
    --to=ville.syrjala@linux.intel.com \
    --cc=dri-devel@lists.freedesktop.org \
    --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.