lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <f4fd280f-19c7-46a3-a8bb-2915f6694c3f@linaro.org>
Date: Thu, 2 May 2024 09:28:27 +0200
From: Neil Armstrong <neil.armstrong@...aro.org>
To: Douglas Anderson <dianders@...omium.org>, dri-devel@...ts.freedesktop.org
Cc: Linus Walleij <linus.walleij@...aro.org>,
 Jani Nikula <jani.nikula@...ux.intel.com>,
 Dmitry Baryshkov <dmitry.baryshkov@...aro.org>,
 Cong Yang <yangcong5@...qin.corp-partner.google.com>,
 Hsin-Yi Wang <hsinyi@...gle.com>, Brian Norris <briannorris@...omium.org>,
 Sam Ravnborg <sam@...nborg.org>,
 Javier Martinez Canillas <javierm@...hat.com>, Joel Selvaraj
 <jo@...amily.in>, lvzhaoxiong@...qin.corp-partner.google.com,
 Daniel Vetter <daniel@...ll.ch>, David Airlie <airlied@...il.com>,
 Jonathan Corbet <corbet@....net>,
 Maarten Lankhorst <maarten.lankhorst@...ux.intel.com>,
 Maxime Ripard <mripard@...nel.org>, Thomas Zimmermann <tzimmermann@...e.de>,
 linux-doc@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: Re: [PATCH v3 5/9] drm/mipi-dsi: Introduce
 mipi_dsi_*_write_seq_multi()

On 01/05/2024 17:41, Douglas Anderson wrote:
> The current mipi_dsi_*_write_seq() macros are non-intutitive because
> they contain a hidden "return" statement that will return out of the
> _caller_ of the macro. Let's mark them as deprecated and instead
> introduce some new macros that are more intuitive.
> 
> These new macros are less optimal when an error occurs but should
> behave more optimally when there is no error. Specifically these new
> macros cause smaller code to get generated and the code size savings
> (less to fetch from RAM, less cache space used, less RAM used) are
> important. Since the error case isn't something we need to optimize
> for and these new macros are easier to understand and more flexible,
> they should be used.
> 
> After converting to use these new functions, one example shows some
> nice savings while also being easier to understand.
> 
> $ scripts/bloat-o-meter \
>    ...after/panel-novatek-nt36672e.ko \
>    ...ctx/panel-novatek-nt36672e.ko
> add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-988 (-988)
> Function                                     old     new   delta
> nt36672e_1080x2408_60hz_init                6236    5248    -988
> Total: Before=10651, After=9663, chg -9.28%
> 
> Signed-off-by: Douglas Anderson <dianders@...omium.org>
> ---
> Right now this patch introduces two new functions in drm_mipi_dsi.c.
> Alternatively we could have changed the prototype of the "chatty"
> functions and made the deprecated macros adapt to the new prototype.
> While this sounds nice, it bloated callers of the deprecated functioin
> a bit because it caused the compiler to emit less optimal code. It
> doesn't seem terrible to add two more functions, so I went that
> way. There may be cases where callers who aren't writing many
> sequences prefer to use the "chatty" versions anyway.
> 
> Changes in v3:
> - Add a TODO item for cleaning up the deprecated macros/functions.
> - Inline kerneldoc comments for struct mipi_dsi_multi_context.
> 
> Changes in v2:
> - New
> 
>   Documentation/gpu/todo.rst     | 18 ++++++++++
>   drivers/gpu/drm/drm_mipi_dsi.c | 56 ++++++++++++++++++++++++++++++
>   include/drm/drm_mipi_dsi.h     | 62 ++++++++++++++++++++++++++++++++++
>   3 files changed, 136 insertions(+)
> 
> diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
> index fb9ad120b141..45a59c176b06 100644
> --- a/Documentation/gpu/todo.rst
> +++ b/Documentation/gpu/todo.rst
> @@ -507,6 +507,24 @@ Contact: Douglas Anderson <dianders@...omium.org>
>   
>   Level: Starter/Intermediate
>   
> +Transition away from using mipi_dsi_*_write_seq()
> +-------------------------------------------------
> +
> +The macros mipi_dsi_generic_write_seq() and mipi_dsi_dcs_write_seq() are
> +non-intuitive because, if there are errors, they return out of the *caller's*
> +function. We should move all callers to use mipi_dsi_generic_write_seq_multi()
> +and mipi_dsi_dcs_write_seq_multi() macros instead.
> +
> +Once all callers are transitioned, the macros and the functions that they call,
> +mipi_dsi_generic_write_chatty() and mipi_dsi_dcs_write_buffer_chatty(), can
> +probably be removed. Alternatively, if people feel like the _multi() variants
> +are overkill for some use cases, we could keep the mipi_dsi_*_write_seq()
> +variants but change them not to return out of the caller.
> +
> +Contact: Douglas Anderson <dianders@...omium.org>
> +
> +Level: Starter
> +
>   
>   Core refactorings
>   =================
> diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
> index 8593d9ed5891..d2957cb692d3 100644
> --- a/drivers/gpu/drm/drm_mipi_dsi.c
> +++ b/drivers/gpu/drm/drm_mipi_dsi.c
> @@ -792,6 +792,34 @@ int mipi_dsi_generic_write_chatty(struct mipi_dsi_device *dsi,
>   }
>   EXPORT_SYMBOL(mipi_dsi_generic_write_chatty);
>   
> +/**
> + * mipi_dsi_generic_write_multi() - mipi_dsi_generic_write_chatty() w/ accum_err
> + * @ctx: Context for multiple DSI transactions
> + * @payload: buffer containing the payload
> + * @size: size of payload buffer
> + *
> + * Like mipi_dsi_generic_write_chatty() but deals with errors in a way that
> + * makes it convenient to make several calls in a row.
> + */
> +void mipi_dsi_generic_write_multi(struct mipi_dsi_multi_context *ctx,
> +				  const void *payload, size_t size)
> +{
> +	struct mipi_dsi_device *dsi = ctx->dsi;
> +	struct device *dev = &dsi->dev;
> +	ssize_t ret;
> +
> +	if (ctx->accum_err)
> +		return;
> +
> +	ret = mipi_dsi_generic_write(dsi, payload, size);
> +	if (ret < 0) {
> +		ctx->accum_err = ret;
> +		dev_err(dev, "sending generic data %*ph failed: %d\n",
> +			(int)size, payload, ctx->accum_err);
> +	}
> +}
> +EXPORT_SYMBOL(mipi_dsi_generic_write_multi);
> +
>   /**
>    * mipi_dsi_generic_read() - receive data using a generic read packet
>    * @dsi: DSI peripheral device
> @@ -908,6 +936,34 @@ int mipi_dsi_dcs_write_buffer_chatty(struct mipi_dsi_device *dsi,
>   }
>   EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer_chatty);
>   
> +/**
> + * mipi_dsi_dcs_write_buffer_multi - mipi_dsi_dcs_write_buffer_chatty() w/ accum_err
> + * @ctx: Context for multiple DSI transactions
> + * @data: buffer containing data to be transmitted
> + * @len: size of transmission buffer
> + *
> + * Like mipi_dsi_dcs_write_buffer_chatty() but deals with errors in a way that
> + * makes it convenient to make several calls in a row.
> + */
> +void mipi_dsi_dcs_write_buffer_multi(struct mipi_dsi_multi_context *ctx,
> +				     const void *data, size_t len)
> +{
> +	struct mipi_dsi_device *dsi = ctx->dsi;
> +	struct device *dev = &dsi->dev;
> +	ssize_t ret;
> +
> +	if (ctx->accum_err)
> +		return;
> +
> +	ret = mipi_dsi_dcs_write_buffer(dsi, data, len);
> +	if (ret < 0) {
> +		ctx->accum_err = ret;
> +		dev_err(dev, "sending dcs data %*ph failed: %d\n",
> +			(int)len, data, ctx->accum_err);
> +	}
> +}
> +EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer_multi);
> +
>   /**
>    * mipi_dsi_dcs_write() - send DCS write command
>    * @dsi: DSI peripheral device
> diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
> index 6d68d9927f46..5e9cad541bd6 100644
> --- a/include/drm/drm_mipi_dsi.h
> +++ b/include/drm/drm_mipi_dsi.h
> @@ -197,6 +197,27 @@ struct mipi_dsi_device {
>   	struct drm_dsc_config *dsc;
>   };
>   
> +/**
> + * struct mipi_dsi_multi_context - Context to call multiple MIPI DSI funcs in a row
> + */
> +struct mipi_dsi_multi_context {
> +	/**
> +	 * @dsi: Pointer to the MIPI DSI device
> +	 */
> +	struct mipi_dsi_device *dsi;
> +
> +	/**
> +	 * @accum_err: Storage for the accumulated error over the multiple calls
> +	 *
> +	 * Init to 0. If a function encounters an error then the error code
> +	 * will be stored here. If you call a function and this points to a
> +	 * non-zero value then the function will be a noop. This allows calling
> +	 * a function many times in a row and just checking the error at the
> +	 * end to see if any of them failed.
> +	 */
> +	int accum_err;
> +};
> +
>   #define MIPI_DSI_MODULE_PREFIX "mipi-dsi:"
>   
>   #define to_mipi_dsi_device(__dev)	container_of_const(__dev, struct mipi_dsi_device, dev)
> @@ -258,6 +279,8 @@ ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload,
>   			       size_t size);
>   int mipi_dsi_generic_write_chatty(struct mipi_dsi_device *dsi,
>   				  const void *payload, size_t size);
> +void mipi_dsi_generic_write_multi(struct mipi_dsi_multi_context *ctx,
> +				  const void *payload, size_t size);
>   ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
>   			      size_t num_params, void *data, size_t size);
>   
> @@ -283,6 +306,8 @@ ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi,
>   				  const void *data, size_t len);
>   int mipi_dsi_dcs_write_buffer_chatty(struct mipi_dsi_device *dsi,
>   				     const void *data, size_t len);
> +void mipi_dsi_dcs_write_buffer_multi(struct mipi_dsi_multi_context *ctx,
> +				     const void *data, size_t len);
>   ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd,
>   			   const void *data, size_t len);
>   ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data,
> @@ -319,6 +344,9 @@ int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi,
>    * This macro will print errors for you and will RETURN FROM THE CALLING
>    * FUNCTION (yes this is non-intuitive) upon error.
>    *
> + * Because of the non-intuitive return behavior, THIS MACRO IS DEPRECATED.
> + * Please replace calls of it with mipi_dsi_generic_write_seq_multi().
> + *
>    * @dsi: DSI peripheral device
>    * @seq: buffer containing the payload
>    */
> @@ -331,12 +359,30 @@ int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi,
>   			return ret;                                            \
>   	} while (0)
>   
> +/**
> + * mipi_dsi_generic_write_seq_multi - transmit data using a generic write packet
> + *
> + * This macro will print errors for you and error handling is optimized for
> + * callers that call this multiple times in a row.
> + *
> + * @ctx: Context for multiple DSI transactions
> + * @seq: buffer containing the payload
> + */
> +#define mipi_dsi_generic_write_seq_multi(ctx, seq...)                \
> +	do {                                                         \
> +		static const u8 d[] = { seq };                       \
> +		mipi_dsi_generic_write_multi(ctx, d, ARRAY_SIZE(d)); \
> +	} while (0)
> +
>   /**
>    * mipi_dsi_dcs_write_seq - transmit a DCS command with payload
>    *
>    * This macro will print errors for you and will RETURN FROM THE CALLING
>    * FUNCTION (yes this is non-intuitive) upon error.
>    *
> + * Because of the non-intuitive return behavior, THIS MACRO IS DEPRECATED.
> + * Please replace calls of it with mipi_dsi_dcs_write_seq_multi().
> + *
>    * @dsi: DSI peripheral device
>    * @cmd: Command
>    * @seq: buffer containing data to be transmitted
> @@ -350,6 +396,22 @@ int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi,
>   			return ret;                                            \
>   	} while (0)
>   
> +/**
> + * mipi_dsi_dcs_write_seq_multi - transmit a DCS command with payload
> + *
> + * This macro will print errors for you and error handling is optimized for
> + * callers that call this multiple times in a row.
> + *
> + * @ctx: Context for multiple DSI transactions
> + * @cmd: Command
> + * @seq: buffer containing data to be transmitted
> + */
> +#define mipi_dsi_dcs_write_seq_multi(ctx, cmd, seq...)                  \
> +	do {                                                            \
> +		static const u8 d[] = { cmd, seq };                     \
> +		mipi_dsi_dcs_write_buffer_multi(ctx, d, ARRAY_SIZE(d)); \
> +	} while (0)
> +
>   /**
>    * struct mipi_dsi_driver - DSI driver
>    * @driver: device driver model driver

Reviewed-by: Neil Armstrong <neil.armstrong@...aro.org>

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ