dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] drm/bridge: ti-sn65dsi86: Fix auxiliary bus lifetime
@ 2023-06-13 13:58 Douglas Anderson
  2023-06-13 18:41 ` Stephen Boyd
  0 siblings, 1 reply; 3+ messages in thread
From: Douglas Anderson @ 2023-06-13 13:58 UTC (permalink / raw)
  To: dri-devel
  Cc: Neil Armstrong, Robert Foss, Andrzej Hajda, Jonas Karlman,
	linux-kernel, Douglas Anderson, Jernej Skrabec, Stephen Boyd,
	Laurent Pinchart

Memory for the "struct device" for any given device isn't supposed to
be released until the device's release() is called. This is important
because someone might be holding a kobject reference to the "struct
device" and might try to access one of its members even after any
other cleanup/uninitialization has happened.

Code analysis of ti-sn65dsi86 shows that this isn't quite right. When
the code was written, it was believed that we could rely on the fact
that the child devices would all be freed before the parent devices
and thus we didn't need to worry about a release() function. While I
still believe that the parent's "struct device" is guaranteed to
outlive the child's "struct device" (because the child holds a kobject
reference to the parent), the parent's "devm" allocated memory is a
different story. That appears to be freed much earlier.

Let's make this better for ti-sn65dsi86 by allocating each auxiliary
with kzalloc and then free that memory in the release().

Fixes: bf73537f411b ("drm/bridge: ti-sn65dsi86: Break GPIO and MIPI-to-eDP bridge into sub-drivers")
Suggested-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---

Changes in v2:
- Check for allocation failure.
- Delete a blank line.

 drivers/gpu/drm/bridge/ti-sn65dsi86.c | 35 +++++++++++++++++----------
 1 file changed, 22 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
index 597ceb7024e0..e3de68f226e8 100644
--- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c
+++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
@@ -170,10 +170,10 @@
  * @pwm_refclk_freq: Cache for the reference clock input to the PWM.
  */
 struct ti_sn65dsi86 {
-	struct auxiliary_device		bridge_aux;
-	struct auxiliary_device		gpio_aux;
-	struct auxiliary_device		aux_aux;
-	struct auxiliary_device		pwm_aux;
+	struct auxiliary_device		*bridge_aux;
+	struct auxiliary_device		*gpio_aux;
+	struct auxiliary_device		*aux_aux;
+	struct auxiliary_device		*pwm_aux;
 
 	struct device			*dev;
 	struct regmap			*regmap;
@@ -464,27 +464,34 @@ static void ti_sn65dsi86_delete_aux(void *data)
 	auxiliary_device_delete(data);
 }
 
-/*
- * AUX bus docs say that a non-NULL release is mandatory, but it makes no
- * sense for the model used here where all of the aux devices are allocated
- * in the single shared structure. We'll use this noop as a workaround.
- */
-static void ti_sn65dsi86_noop(struct device *dev) {}
+static void ti_sn65dsi86_aux_device_release(struct device *dev)
+{
+	struct auxiliary_device *aux = container_of(dev, struct auxiliary_device, dev);
+
+	kfree(aux);
+}
 
 static int ti_sn65dsi86_add_aux_device(struct ti_sn65dsi86 *pdata,
-				       struct auxiliary_device *aux,
+				       struct auxiliary_device **aux_out,
 				       const char *name)
 {
 	struct device *dev = pdata->dev;
+	struct auxiliary_device *aux;
 	int ret;
 
+	aux = kzalloc(sizeof(*aux), GFP_KERNEL);
+	if (!aux)
+		return -ENOMEM;
+
 	aux->name = name;
 	aux->dev.parent = dev;
-	aux->dev.release = ti_sn65dsi86_noop;
+	aux->dev.release = ti_sn65dsi86_aux_device_release;
 	device_set_of_node_from_dev(&aux->dev, dev);
 	ret = auxiliary_device_init(aux);
-	if (ret)
+	if (ret) {
+		kfree(aux);
 		return ret;
+	}
 	ret = devm_add_action_or_reset(dev, ti_sn65dsi86_uninit_aux, aux);
 	if (ret)
 		return ret;
@@ -493,6 +500,8 @@ static int ti_sn65dsi86_add_aux_device(struct ti_sn65dsi86 *pdata,
 	if (ret)
 		return ret;
 	ret = devm_add_action_or_reset(dev, ti_sn65dsi86_delete_aux, aux);
+	if (!ret)
+		*aux_out = aux;
 
 	return ret;
 }
-- 
2.41.0.162.gfafddb0af9-goog


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] drm/bridge: ti-sn65dsi86: Fix auxiliary bus lifetime
  2023-06-13 13:58 [PATCH v2] drm/bridge: ti-sn65dsi86: Fix auxiliary bus lifetime Douglas Anderson
@ 2023-06-13 18:41 ` Stephen Boyd
  2023-06-26 18:13   ` Doug Anderson
  0 siblings, 1 reply; 3+ messages in thread
From: Stephen Boyd @ 2023-06-13 18:41 UTC (permalink / raw)
  To: Douglas Anderson, dri-devel
  Cc: Neil Armstrong, Robert Foss, Andrzej Hajda, Jonas Karlman,
	linux-kernel, Jernej Skrabec, Laurent Pinchart

Quoting Douglas Anderson (2023-06-13 06:58:13)
> Memory for the "struct device" for any given device isn't supposed to
> be released until the device's release() is called. This is important
> because someone might be holding a kobject reference to the "struct
> device" and might try to access one of its members even after any
> other cleanup/uninitialization has happened.
>
> Code analysis of ti-sn65dsi86 shows that this isn't quite right. When
> the code was written, it was believed that we could rely on the fact
> that the child devices would all be freed before the parent devices
> and thus we didn't need to worry about a release() function. While I
> still believe that the parent's "struct device" is guaranteed to
> outlive the child's "struct device" (because the child holds a kobject
> reference to the parent), the parent's "devm" allocated memory is a
> different story. That appears to be freed much earlier.
>
> Let's make this better for ti-sn65dsi86 by allocating each auxiliary
> with kzalloc and then free that memory in the release().
>
> Fixes: bf73537f411b ("drm/bridge: ti-sn65dsi86: Break GPIO and MIPI-to-eDP bridge into sub-drivers")
> Suggested-by: Stephen Boyd <swboyd@chromium.org>
> Signed-off-by: Douglas Anderson <dianders@chromium.org>
> ---

Reviewed-by: Stephen Boyd <swboyd@chromium.org>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] drm/bridge: ti-sn65dsi86: Fix auxiliary bus lifetime
  2023-06-13 18:41 ` Stephen Boyd
@ 2023-06-26 18:13   ` Doug Anderson
  0 siblings, 0 replies; 3+ messages in thread
From: Doug Anderson @ 2023-06-26 18:13 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Neil Armstrong, Robert Foss, Andrzej Hajda, Jonas Karlman,
	linux-kernel, Jernej Skrabec, dri-devel, Laurent Pinchart

Hi,

On Tue, Jun 13, 2023 at 11:41 AM Stephen Boyd <swboyd@chromium.org> wrote:
>
> Quoting Douglas Anderson (2023-06-13 06:58:13)
> > Memory for the "struct device" for any given device isn't supposed to
> > be released until the device's release() is called. This is important
> > because someone might be holding a kobject reference to the "struct
> > device" and might try to access one of its members even after any
> > other cleanup/uninitialization has happened.
> >
> > Code analysis of ti-sn65dsi86 shows that this isn't quite right. When
> > the code was written, it was believed that we could rely on the fact
> > that the child devices would all be freed before the parent devices
> > and thus we didn't need to worry about a release() function. While I
> > still believe that the parent's "struct device" is guaranteed to
> > outlive the child's "struct device" (because the child holds a kobject
> > reference to the parent), the parent's "devm" allocated memory is a
> > different story. That appears to be freed much earlier.
> >
> > Let's make this better for ti-sn65dsi86 by allocating each auxiliary
> > with kzalloc and then free that memory in the release().
> >
> > Fixes: bf73537f411b ("drm/bridge: ti-sn65dsi86: Break GPIO and MIPI-to-eDP bridge into sub-drivers")
> > Suggested-by: Stephen Boyd <swboyd@chromium.org>
> > Signed-off-by: Douglas Anderson <dianders@chromium.org>
> > ---
>
> Reviewed-by: Stephen Boyd <swboyd@chromium.org>

Pushed to drm-misc-fixes:

7aa83fbd712a drm/bridge: ti-sn65dsi86: Fix auxiliary bus lifetime

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2023-06-26 18:13 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-13 13:58 [PATCH v2] drm/bridge: ti-sn65dsi86: Fix auxiliary bus lifetime Douglas Anderson
2023-06-13 18:41 ` Stephen Boyd
2023-06-26 18:13   ` Doug Anderson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).