Re: [PATCH v3 4/4] drm/panel: find_panel_by_fwnode() return a counted reference

"Luca Ceresoli" <[email protected]>
Newsgroups org.kernel.vger.linux-renesas-soc,dev.linux.lists.imx,dev.linux.lists.linux-sunxi,org.freedesktop.lists.dri-devel,org.infradead.lists.linux-rockchip,org.kernel.vger.linux-kernel,org.kernel.vger.linux-mips,org.kernel.vger.linux-samsung-soc,org.kernel.vger.linux-tegra
Message-ID <[email protected]>
Hello Albert,

On Fri Jul 17, 2026 at 4:02 PM CEST, Albert Esteve wrote:
> find_panel_by_fwnode() is the fwnode-based counterpart to
> of_drm_find_panel(), used internally by drm_panel_add_follower().
> Like of_drm_find_panel(), it returned an unrefcounted pointer,
> leaving a window where the panel could be freed between the lookup
> and first use.
>
> drm_panel_add_follower() worked around the missing panel kref by
> calling get_device() on the panel's underlying struct device.
> However, get_device() only prevents the device kobject from being freed.
> It does not prevent the panel's kzalloc()'d container memory from being
> released when the kref reaches zero.
>
> Apply the same fix: call drm_panel_get() under panel_lock before
> returning. Since find_panel_by_fwnode() now transfers a counted
> reference to drm_panel_add_follower(), drm_panel_remove_follower()
> must balance it with a matching drm_panel_put().
>
> Acked-by: Maxime Ripard <[email protected]>
> Signed-off-by: Albert Esteve <[email protected]>
> ---
>  drivers/gpu/drm/drm_panel.c | 10 +++++++++-
>  1 file changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
> index 72cf86253c0cd..a00ae98ed0956 100644
> --- a/drivers/gpu/drm/drm_panel.c
> +++ b/drivers/gpu/drm/drm_panel.c
> @@ -542,7 +542,13 @@ int of_drm_get_panel_orientation(const struct device_node *np,
>  EXPORT_SYMBOL(of_drm_get_panel_orientation);
>  #endif
>
> -/* Find panel by fwnode. This should be identical to of_drm_find_panel(). */
> +/*
> + * Find panel by fwnode, returning a counted reference.
> + *
> + * Behaves identically to of_drm_find_panel(). On success the returned
> + * pointer has been passed through drm_panel_get(); the caller must call
> + * drm_panel_put() when done with it.
> + */
>  static struct drm_panel *find_panel_by_fwnode(const struct fwnode_handle *fwnode)
>  {
>  	struct drm_panel *panel;
> @@ -554,6 +560,7 @@ static struct drm_panel *find_panel_by_fwnode(const struct fwnode_handle *fwnode
>
>  	list_for_each_entry(panel, &panel_list, list) {
>  		if (dev_fwnode(panel->dev) == fwnode) {
> +			drm_panel_get(panel);
>  			mutex_unlock(&panel_lock);
>  			return panel;
>  		}
> @@ -690,6 +697,7 @@ void drm_panel_remove_follower(struct drm_panel_follower *follower)
>  	mutex_unlock(&panel->follower_lock);
>
>  	put_device(panel->dev);
> +	drm_panel_put(panel);

Based on your description, can we drop the get_device/put_device() now?

That can be done as a future cleanup, so:
Reviewed-by: Luca Ceresoli <[email protected]>

Luca

--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.