* [PATCH v3 0/4] drm/panel: Panel Refcounting infrastructure
@ 2025-03-31 2:24 Anusha Srivatsa
2025-03-31 2:24 ` [PATCH v3 1/4] drm/panel: Add new helpers for refcounted panel allocatons Anusha Srivatsa
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Anusha Srivatsa @ 2025-03-31 2:24 UTC (permalink / raw)
To: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter
Cc: dri-devel, linux-kernel, Luca Ceresoli, Anusha Srivatsa
This series adds the infrastructure needed for the refcounting
allocations for panels similar to Luca's efforts with bridges.
Underlying intention and idea is the same - avoid use-after-free
situations in panels. Get reference to panel when in use and put
the reference back (down) when not in use.
Once this gets approved, rest of the drivers will have to be
mass converted to use this API. All the callers of of_drm_find_panel()
will have to be converted too.
Tried to split the patches as suggested in the RFC series[1].
Also fixed the connector used during panel_init to be the one
passed by driver.
Patch 4 was not suggested or part of my initial work. Added it
after looking at the comments Luca's v8 of the bridge series
received.[2]
[1] -> https://patchwork.freedesktop.org/series/146236/
[2] -> https://patchwork.freedesktop.org/series/146306/#rev2
Suggested-by: Maxime Ripard <mripard@kernel.org>
Signed-off-by: Anusha Srivatsa <asrivats@redhat.com>
---
Changes in v3:
- Move the include from patch 1 to patch 2 where it is actually used
- Move the refcounting documentation out from the returns section to the
actual helper socumentation.
- Code style changes. Move the version changes after the s-o-b.
- Link to v2: https://lore.kernel.org/r/20250327-b4-panel-refcounting-v2-0-b5f5ca551f95@redhat.com
Changes in v2:
- Change drm_panel_put() to return void.
- Export drm_panel_get()/put()
- Code cleanups: add missing return documentation, improve documentation
in commit logs.
- Link to v1: https://lore.kernel.org/r/20250325-b4-panel-refcounting-v1-0-4e2bf5d19c5d@redhat.com
---
Anusha Srivatsa (4):
drm/panel: Add new helpers for refcounted panel allocatons
drm/panel: Add refcount support
drm/panel: deprecate old-style panel allocation
drm/panel/panel-simple: Use the new allocation in place of devm_kzalloc()
drivers/gpu/drm/drm_panel.c | 92 +++++++++++++++++++++++++++++++++++-
drivers/gpu/drm/panel/panel-simple.c | 9 ++--
include/drm/drm_panel.h | 39 +++++++++++++++
3 files changed, 133 insertions(+), 7 deletions(-)
---
base-commit: 372a9ca3c1f2ea10dd05a5d5008d055bc9536ced
change-id: 20250324-b4-panel-refcounting-40ab56aa34f7
Best regards,
--
Anusha Srivatsa <asrivats@redhat.com>
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v3 1/4] drm/panel: Add new helpers for refcounted panel allocatons
2025-03-31 2:24 [PATCH v3 0/4] drm/panel: Panel Refcounting infrastructure Anusha Srivatsa
@ 2025-03-31 2:24 ` Anusha Srivatsa
2025-03-31 14:09 ` Maxime Ripard
2025-03-31 2:24 ` [PATCH v3 2/4] drm/panel: Add refcount support Anusha Srivatsa
` (2 subsequent siblings)
3 siblings, 1 reply; 6+ messages in thread
From: Anusha Srivatsa @ 2025-03-31 2:24 UTC (permalink / raw)
To: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter
Cc: dri-devel, linux-kernel, Luca Ceresoli, Anusha Srivatsa
Introduce reference counted allocations for panels to avoid
use-after-free. The patch adds the macro devm_drm_bridge_alloc()
to allocate a new refcounted panel. Followed the documentation for
drmm_encoder_alloc() and devm_drm_dev_alloc and other similar
implementations for this purpose.
Reviewed-by: Maxime Ripard <mripard@kernel.org>
Signed-off-by: Anusha Srivatsa <asrivats@redhat.com>
---
v3: Remove include. Fix typos. Code style corrections (Luca)
- Move the documentation to the main helper instead of in returns
(Maxime)
v2: Better documentation for connector_type field - follow drm_panel_init
documentation. (Luca)
- Clarify the refcount initialisation in comments.(Maxime)
- Correct the documentation of the return type (Maxime)
---
drivers/gpu/drm/drm_panel.c | 25 +++++++++++++++++++++++++
include/drm/drm_panel.h | 24 ++++++++++++++++++++++++
2 files changed, 49 insertions(+)
diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
index c627e42a7ce70459f50eb5095fffc806ca45dabf..bdeab5710ee324dc1742fbc77582250960556308 100644
--- a/drivers/gpu/drm/drm_panel.c
+++ b/drivers/gpu/drm/drm_panel.c
@@ -355,6 +355,31 @@ struct drm_panel *of_drm_find_panel(const struct device_node *np)
}
EXPORT_SYMBOL(of_drm_find_panel);
+void *__devm_drm_panel_alloc(struct device *dev, size_t size, size_t offset,
+ const struct drm_panel_funcs *funcs,
+ int connector_type)
+{
+ void *container;
+ struct drm_panel *panel;
+
+ if (!funcs) {
+ dev_warn(dev, "Missing funcs pointer\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ container = devm_kzalloc(dev, size, GFP_KERNEL);
+ if (!container)
+ return ERR_PTR(-ENOMEM);
+
+ panel = container + offset;
+ panel->funcs = funcs;
+
+ drm_panel_init(panel, dev, funcs, connector_type);
+
+ return container;
+}
+EXPORT_SYMBOL(__devm_drm_panel_alloc);
+
/**
* of_drm_get_panel_orientation - look up the orientation of the panel through
* the "rotation" binding from a device tree node
diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
index a9c042c8dea1a82ef979c7a68204e0b55483fc28..97a5457b64fbbe9c91c6a4f41b8e1fbfe4fa604e 100644
--- a/include/drm/drm_panel.h
+++ b/include/drm/drm_panel.h
@@ -268,6 +268,30 @@ struct drm_panel {
bool enabled;
};
+void *__devm_drm_panel_alloc(struct device *dev, size_t size, size_t offset,
+ const struct drm_panel_funcs *funcs,
+ int connector_type);
+
+/**
+ * devm_drm_panel_alloc - Allocate and initialize a refcounted panel.
+ * The reference count is initialised to 1 and is automatically given back
+ * by devm action.
+ *
+ * @dev: struct device of the panel device
+ * @type: the type of the struct which contains struct &drm_panel
+ * @member: the name of the &drm_panel within @type
+ * @funcs: callbacks for this panel
+ * @connector_type: the connector type (DRM_MODE_CONNECTOR_*) corresponding to
+ * the panel interface
+ *
+ * Returns:
+ * Pointer to container structure embedding the panel, ERR_PTR on failure.
+ */
+#define devm_drm_panel_alloc(dev, type, member, funcs, connector_type) \
+ ((type *)__devm_drm_panel_alloc(dev, sizeof(type), \
+ offsetof(type, member), funcs, \
+ connector_type))
+
void drm_panel_init(struct drm_panel *panel, struct device *dev,
const struct drm_panel_funcs *funcs,
int connector_type);
--
2.48.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v3 2/4] drm/panel: Add refcount support
2025-03-31 2:24 [PATCH v3 0/4] drm/panel: Panel Refcounting infrastructure Anusha Srivatsa
2025-03-31 2:24 ` [PATCH v3 1/4] drm/panel: Add new helpers for refcounted panel allocatons Anusha Srivatsa
@ 2025-03-31 2:24 ` Anusha Srivatsa
2025-03-31 2:24 ` [PATCH v3 3/4] drm/panel: deprecate old-style panel allocation Anusha Srivatsa
2025-03-31 2:24 ` [PATCH v3 4/4] drm/panel/panel-simple: Use the new allocation in place of devm_kzalloc() Anusha Srivatsa
3 siblings, 0 replies; 6+ messages in thread
From: Anusha Srivatsa @ 2025-03-31 2:24 UTC (permalink / raw)
To: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter
Cc: dri-devel, linux-kernel, Luca Ceresoli, Anusha Srivatsa
Allocate panel via reference counting. Add _get() and _put() helper
functions to ensure panel allocations are refcounted. Avoid use after
free by ensuring panel pointer is valid and can be usable till the last
reference is put.
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Reviewed-by: Maxime Ripard <mripard@kernel.org>
Signed-off-by: Anusha Srivatsa <asrivats@redhat.com>
---
v3: Add include in this patch (Luca)
v2: Export drm_panel_put/get() (Maxime)
- Change commit log with better workding (Luca, Maxime)
- Change drm_panel_put() to return void (Luca)
- Code Cleanups - add return in documentation, replace bridge to
panel (Luca)
---
drivers/gpu/drm/drm_panel.c | 64 ++++++++++++++++++++++++++++++++++++++++++++-
include/drm/drm_panel.h | 15 +++++++++++
2 files changed, 78 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
index bdeab5710ee324dc1742fbc77582250960556308..7b17531d85a4dc3031709919564d2e4d8332f748 100644
--- a/drivers/gpu/drm/drm_panel.c
+++ b/drivers/gpu/drm/drm_panel.c
@@ -355,24 +355,86 @@ struct drm_panel *of_drm_find_panel(const struct device_node *np)
}
EXPORT_SYMBOL(of_drm_find_panel);
+static void __drm_panel_free(struct kref *kref)
+{
+ struct drm_panel *panel = container_of(kref, struct drm_panel, refcount);
+
+ kfree(panel->container);
+}
+
+/**
+ * drm_panel_get - Acquire a panel reference
+ * @panel: DRM panel
+ *
+ * This function increments the panel's refcount.
+ * Returns:
+ * Pointer to @panel
+ */
+struct drm_panel *drm_panel_get(struct drm_panel *panel)
+{
+ if (!panel)
+ return panel;
+
+ kref_get(&panel->refcount);
+
+ return panel;
+}
+EXPORT_SYMBOL(drm_panel_get);
+
+/**
+ * drm_panel_put - Release a panel reference
+ * @panel: DRM panel
+ *
+ * This function decrements the panel's reference count and frees the
+ * object if the reference count drops to zero.
+ */
+void drm_panel_put(struct drm_panel *panel)
+{
+ if (panel)
+ kref_put(&panel->refcount, __drm_panel_free);
+}
+EXPORT_SYMBOL(drm_panel_put);
+
+/**
+ * drm_panel_put_void - wrapper to drm_panel_put() taking a void pointer
+ *
+ * @data: pointer to @struct drm_panel, cast to a void pointer
+ *
+ * Wrapper of drm_panel_put() to be used when a function taking a void
+ * pointer is needed, for example as a devm action.
+ */
+static void drm_panel_put_void(void *data)
+{
+ struct drm_panel *panel = (struct drm_panel *)data;
+
+ drm_panel_put(panel);
+}
+
void *__devm_drm_panel_alloc(struct device *dev, size_t size, size_t offset,
const struct drm_panel_funcs *funcs,
int connector_type)
{
void *container;
struct drm_panel *panel;
+ int err;
if (!funcs) {
dev_warn(dev, "Missing funcs pointer\n");
return ERR_PTR(-EINVAL);
}
- container = devm_kzalloc(dev, size, GFP_KERNEL);
+ container = kzalloc(size, GFP_KERNEL);
if (!container)
return ERR_PTR(-ENOMEM);
panel = container + offset;
+ panel->container = container;
panel->funcs = funcs;
+ kref_init(&panel->refcount);
+
+ err = devm_add_action_or_reset(dev, drm_panel_put_void, panel);
+ if (err)
+ return ERR_PTR(err);
drm_panel_init(panel, dev, funcs, connector_type);
diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
index 97a5457b64fbbe9c91c6a4f41b8e1fbfe4fa604e..095e03c6e660d838b227e7a5cf8ca9b88c4bdc3d 100644
--- a/include/drm/drm_panel.h
+++ b/include/drm/drm_panel.h
@@ -28,6 +28,7 @@
#include <linux/errno.h>
#include <linux/list.h>
#include <linux/mutex.h>
+#include <linux/kref.h>
struct backlight_device;
struct dentry;
@@ -266,6 +267,17 @@ struct drm_panel {
* If true then the panel has been enabled.
*/
bool enabled;
+
+ /**
+ * @container: Pointer to the private driver struct embedding this
+ * @struct drm_panel.
+ */
+ void *container;
+
+ /**
+ * @refcount: reference count of users referencing this panel.
+ */
+ struct kref refcount;
};
void *__devm_drm_panel_alloc(struct device *dev, size_t size, size_t offset,
@@ -296,6 +308,9 @@ void drm_panel_init(struct drm_panel *panel, struct device *dev,
const struct drm_panel_funcs *funcs,
int connector_type);
+struct drm_panel *drm_panel_get(struct drm_panel *panel);
+void drm_panel_put(struct drm_panel *panel);
+
void drm_panel_add(struct drm_panel *panel);
void drm_panel_remove(struct drm_panel *panel);
--
2.48.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v3 3/4] drm/panel: deprecate old-style panel allocation
2025-03-31 2:24 [PATCH v3 0/4] drm/panel: Panel Refcounting infrastructure Anusha Srivatsa
2025-03-31 2:24 ` [PATCH v3 1/4] drm/panel: Add new helpers for refcounted panel allocatons Anusha Srivatsa
2025-03-31 2:24 ` [PATCH v3 2/4] drm/panel: Add refcount support Anusha Srivatsa
@ 2025-03-31 2:24 ` Anusha Srivatsa
2025-03-31 2:24 ` [PATCH v3 4/4] drm/panel/panel-simple: Use the new allocation in place of devm_kzalloc() Anusha Srivatsa
3 siblings, 0 replies; 6+ messages in thread
From: Anusha Srivatsa @ 2025-03-31 2:24 UTC (permalink / raw)
To: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter
Cc: dri-devel, linux-kernel, Luca Ceresoli, Anusha Srivatsa
Start moving to the new refcounted allocations using
the new API devm_drm_panel_alloc(). Deprecate any other
allocation.
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Reviewed-by: Maxime Ripard <mripard@kernel.org>
Signed-off-by: Anusha Srivatsa <asrivats@redhat.com>
---
v3: none
v2: make the documentation changes in v1 more precise (Maxime)
---
drivers/gpu/drm/drm_panel.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
index 7b17531d85a4dc3031709919564d2e4d8332f748..870bf8d471ee9c5fe65d88acc13661cacd883b9b 100644
--- a/drivers/gpu/drm/drm_panel.c
+++ b/drivers/gpu/drm/drm_panel.c
@@ -74,8 +74,9 @@ EXPORT_SYMBOL(drm_panel_init);
* drm_panel_add - add a panel to the global registry
* @panel: panel to add
*
- * Add a panel to the global registry so that it can be looked up by display
- * drivers.
+ * Add a panel to the global registry so that it can be looked
+ * up by display drivers. The panel to be added must have been
+ * allocated by devm_drm_panel_alloc().
*/
void drm_panel_add(struct drm_panel *panel)
{
--
2.48.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v3 4/4] drm/panel/panel-simple: Use the new allocation in place of devm_kzalloc()
2025-03-31 2:24 [PATCH v3 0/4] drm/panel: Panel Refcounting infrastructure Anusha Srivatsa
` (2 preceding siblings ...)
2025-03-31 2:24 ` [PATCH v3 3/4] drm/panel: deprecate old-style panel allocation Anusha Srivatsa
@ 2025-03-31 2:24 ` Anusha Srivatsa
3 siblings, 0 replies; 6+ messages in thread
From: Anusha Srivatsa @ 2025-03-31 2:24 UTC (permalink / raw)
To: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter
Cc: dri-devel, linux-kernel, Luca Ceresoli, Anusha Srivatsa
Start using the new helper that does the refcounted
allocations.
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Reviewed-by: Maxime Ripard <mripard@kernel.org>
Signed-off-by: Anusha Srivatsa <asrivats@redhat.com>
---
v3: none.
v2: check error condition (Luca)
---
drivers/gpu/drm/panel/panel-simple.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index 6ba600f97aa4c8daae577823fcf17ef31b0eb46f..df718c4a86cb7dc0cd126e807d33306e5a21d8a0 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -579,9 +579,10 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
u32 bus_flags;
int err;
- panel = devm_kzalloc(dev, sizeof(*panel), GFP_KERNEL);
- if (!panel)
- return -ENOMEM;
+ panel = devm_drm_panel_alloc(dev, struct panel_simple, base,
+ &panel_simple_funcs, desc->connector_type);
+ if (IS_ERR(panel))
+ return PTR_ERR(panel);
panel->desc = desc;
@@ -694,8 +695,6 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
pm_runtime_set_autosuspend_delay(dev, 1000);
pm_runtime_use_autosuspend(dev);
- drm_panel_init(&panel->base, dev, &panel_simple_funcs, connector_type);
-
err = drm_panel_of_backlight(&panel->base);
if (err) {
dev_err_probe(dev, err, "Could not find backlight\n");
--
2.48.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3 1/4] drm/panel: Add new helpers for refcounted panel allocatons
2025-03-31 2:24 ` [PATCH v3 1/4] drm/panel: Add new helpers for refcounted panel allocatons Anusha Srivatsa
@ 2025-03-31 14:09 ` Maxime Ripard
0 siblings, 0 replies; 6+ messages in thread
From: Maxime Ripard @ 2025-03-31 14:09 UTC (permalink / raw)
To: Anusha Srivatsa
Cc: Neil Armstrong, Jessica Zhang, Maarten Lankhorst,
Thomas Zimmermann, David Airlie, Simona Vetter, dri-devel,
linux-kernel, Luca Ceresoli
[-- Attachment #1: Type: text/plain, Size: 1340 bytes --]
On Sun, Mar 30, 2025 at 10:24:12PM -0400, Anusha Srivatsa wrote:
> diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
> index a9c042c8dea1a82ef979c7a68204e0b55483fc28..97a5457b64fbbe9c91c6a4f41b8e1fbfe4fa604e 100644
> --- a/include/drm/drm_panel.h
> +++ b/include/drm/drm_panel.h
> @@ -268,6 +268,30 @@ struct drm_panel {
> bool enabled;
> };
>
> +void *__devm_drm_panel_alloc(struct device *dev, size_t size, size_t offset,
> + const struct drm_panel_funcs *funcs,
> + int connector_type);
> +
> +/**
> + * devm_drm_panel_alloc - Allocate and initialize a refcounted panel.
> + * The reference count is initialised to 1 and is automatically given back
> + * by devm action.
No. I told you in my previous email that it needed to be between the arguments and returns
sections ...
> + * @dev: struct device of the panel device
> + * @type: the type of the struct which contains struct &drm_panel
> + * @member: the name of the &drm_panel within @type
> + * @funcs: callbacks for this panel
> + * @connector_type: the connector type (DRM_MODE_CONNECTOR_*) corresponding to
> + * the panel interface
... So here, just like you did for all the other functions you introduced.
Also, there's no reference counting yet, so that paragraph should be in
your second patch.
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-03-31 14:09 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-03-31 2:24 [PATCH v3 0/4] drm/panel: Panel Refcounting infrastructure Anusha Srivatsa
2025-03-31 2:24 ` [PATCH v3 1/4] drm/panel: Add new helpers for refcounted panel allocatons Anusha Srivatsa
2025-03-31 14:09 ` Maxime Ripard
2025-03-31 2:24 ` [PATCH v3 2/4] drm/panel: Add refcount support Anusha Srivatsa
2025-03-31 2:24 ` [PATCH v3 3/4] drm/panel: deprecate old-style panel allocation Anusha Srivatsa
2025-03-31 2:24 ` [PATCH v3 4/4] drm/panel/panel-simple: Use the new allocation in place of devm_kzalloc() Anusha Srivatsa
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®