* [PATCH v1 0/5] drm/mediatek: Cleanups and sanitization
@ 2025-04-02 8:36 AngeloGioacchino Del Regno
2025-04-02 8:36 ` [PATCH v1 1/5] drm/mediatek: mtk_drm_drv: Fix kobject put for mtk_mutex device ptr AngeloGioacchino Del Regno
` (4 more replies)
0 siblings, 5 replies; 12+ messages in thread
From: AngeloGioacchino Del Regno @ 2025-04-02 8:36 UTC (permalink / raw)
To: chunkuang.hu
Cc: p.zabel, airlied, simona, matthias.bgg,
angelogioacchino.delregno, nancy.lin, ck.hu, djkurtz, littlecvr,
bibby.hsieh, dri-devel, linux-mediatek, linux-kernel,
linux-arm-kernel, wenst, kernel
During probe, the mediatek-drm drivers take a bunch of kobject
references for the various component sub-drivers and for the
mmsys/mutex handles.
Unfortunately, the refcount is not correctly decremented in some
cases, and not correctly incremented in some others, leading to
refcount_t overflows *or* underflows depending on where the code
fails during platform driver probe or during component bind.
This means that if mediatek-drm or any component of it returns a
probe deferral, and if this happens "too many times" (where too
many equals to around 3-5 times, and that's happening especially
when outer drivers are compiled as module while mediatek-drm is
built-in), it creates a whole bunch of badnesses.
This series sanitizes the freeing of the acquired kobjects in
mediatek-drm - especially in the multi-mmsys (multi-vdo) case.
While at it, this also moves the ISR enablement and disablement
to the component bind/unbind callbacks respectively, while keeping
the ISR installation to the probe function: this is done to avoid
leaks and to avoid entering ISRs for OVL/RDMA after those are
unbound (as that'd be dangerous, other than useless, because those
could access memory that doesn't belong to those drivers anymore,
as pointers may not have been set to NULL...!).
As an example, this is the reason (if not one of the reasons) for
a boot failure seen on the MT8195 Tomato Chromebook, pointed out
by KernelCI.
AngeloGioacchino Del Regno (5):
drm/mediatek: mtk_drm_drv: Fix kobject put for mtk_mutex device ptr
drm/mediatek: Fix kobject put for component sub-drivers
drm/mediatek: mtk_drm_drv: Unbind secondary mmsys components on err
drm/mediatek: mtk_disp_ovl: Enable/disable interrupt on bind/unbind
drm/mediatek: mtk_disp_rdma: Enable/disable interrupt on bind/unbind
drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 19 +++++++++----
drivers/gpu/drm/mediatek/mtk_disp_rdma.c | 35 ++++++++++++++----------
drivers/gpu/drm/mediatek/mtk_drm_drv.c | 31 +++++++++++++++------
3 files changed, 57 insertions(+), 28 deletions(-)
--
2.48.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v1 1/5] drm/mediatek: mtk_drm_drv: Fix kobject put for mtk_mutex device ptr
2025-04-02 8:36 [PATCH v1 0/5] drm/mediatek: Cleanups and sanitization AngeloGioacchino Del Regno
@ 2025-04-02 8:36 ` AngeloGioacchino Del Regno
2025-04-02 10:14 ` Chen-Yu Tsai
2025-04-02 8:36 ` [PATCH v1 2/5] drm/mediatek: Fix kobject put for component sub-drivers AngeloGioacchino Del Regno
` (3 subsequent siblings)
4 siblings, 1 reply; 12+ messages in thread
From: AngeloGioacchino Del Regno @ 2025-04-02 8:36 UTC (permalink / raw)
To: chunkuang.hu
Cc: p.zabel, airlied, simona, matthias.bgg,
angelogioacchino.delregno, nancy.lin, ck.hu, djkurtz, littlecvr,
bibby.hsieh, dri-devel, linux-mediatek, linux-kernel,
linux-arm-kernel, wenst, kernel
This driver is taking a kobject for mtk_mutex only once per mmsys
device for each drm-mediatek driver instance, differently from the
behavior with other components, but it is decrementing the kobj's
refcount in a loop and once per mmsys: this is not right and will
result in a refcount_t underflow warning when mediatek-drm returns
multiple probe deferrals in one boot (or when manually bound and
unbound).
Besides that, the refcount for mutex_dev was not decremented for
error cases in mtk_drm_bind(), causing another refcount_t warning
but this time for overflow, when the failure happens not during
driver bind but during component bind.
In order to fix one of the reasons why this is happening, remove
the put_device(xx->mutex_dev) loop from the mtk_drm_kms_init()'s
put_mutex_dev label (and drop the label) and add a single call to
correctly free the single incremented refcount of mutex_dev to
the mtk_drm_unbind() function to fix the refcount_t underflow.
Moreover, add the same call to the error cases in mtk_drm_bind()
to fix the refcount_t overflow.
Fixes: 1ef7ed48356c ("drm/mediatek: Modify mediatek-drm for mt8195 multi mmsys support")
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/gpu/drm/mediatek/mtk_drm_drv.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index e09578756de0..a8fbccb50c74 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -464,7 +464,7 @@ static int mtk_drm_kms_init(struct drm_device *drm)
ret = drmm_mode_config_init(drm);
if (ret)
- goto put_mutex_dev;
+ return ret;
drm->mode_config.min_width = 64;
drm->mode_config.min_height = 64;
@@ -483,7 +483,7 @@ static int mtk_drm_kms_init(struct drm_device *drm)
drm->dev_private = private->all_drm_private[i];
ret = component_bind_all(private->all_drm_private[i]->dev, drm);
if (ret)
- goto put_mutex_dev;
+ return ret;
}
/*
@@ -576,9 +576,6 @@ static int mtk_drm_kms_init(struct drm_device *drm)
err_component_unbind:
for (i = 0; i < private->data->mmsys_dev_num; i++)
component_unbind_all(private->all_drm_private[i]->dev, drm);
-put_mutex_dev:
- for (i = 0; i < private->data->mmsys_dev_num; i++)
- put_device(private->all_drm_private[i]->mutex_dev);
return ret;
}
@@ -649,8 +646,10 @@ static int mtk_drm_bind(struct device *dev)
return 0;
drm = drm_dev_alloc(&mtk_drm_driver, dev);
- if (IS_ERR(drm))
- return PTR_ERR(drm);
+ if (IS_ERR(drm)) {
+ ret = PTR_ERR(drm);
+ goto err_put_dev;
+ }
private->drm_master = true;
drm->dev_private = private;
@@ -676,6 +675,8 @@ static int mtk_drm_bind(struct device *dev)
drm_dev_put(drm);
for (i = 0; i < private->data->mmsys_dev_num; i++)
private->all_drm_private[i]->drm = NULL;
+err_put_dev:
+ put_device(private->mutex_dev);
return ret;
}
@@ -688,6 +689,8 @@ static void mtk_drm_unbind(struct device *dev)
drm_dev_unregister(private->drm);
mtk_drm_kms_deinit(private->drm);
drm_dev_put(private->drm);
+
+ put_device(private->mutex_dev);
}
private->mtk_drm_bound = false;
private->drm_master = false;
--
2.48.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v1 2/5] drm/mediatek: Fix kobject put for component sub-drivers
2025-04-02 8:36 [PATCH v1 0/5] drm/mediatek: Cleanups and sanitization AngeloGioacchino Del Regno
2025-04-02 8:36 ` [PATCH v1 1/5] drm/mediatek: mtk_drm_drv: Fix kobject put for mtk_mutex device ptr AngeloGioacchino Del Regno
@ 2025-04-02 8:36 ` AngeloGioacchino Del Regno
2025-04-02 10:18 ` Chen-Yu Tsai
2025-04-02 8:36 ` [PATCH v1 3/5] drm/mediatek: mtk_drm_drv: Unbind secondary mmsys components on err AngeloGioacchino Del Regno
` (2 subsequent siblings)
4 siblings, 1 reply; 12+ messages in thread
From: AngeloGioacchino Del Regno @ 2025-04-02 8:36 UTC (permalink / raw)
To: chunkuang.hu
Cc: p.zabel, airlied, simona, matthias.bgg,
angelogioacchino.delregno, nancy.lin, ck.hu, djkurtz, littlecvr,
bibby.hsieh, dri-devel, linux-mediatek, linux-kernel,
linux-arm-kernel, wenst, kernel
In function mtk_drm_get_all_priv(), this driver is incrementing
the refcount for the sub-drivers of mediatek-drm with a call to
device_find_child() when taking a reference to all of those child
devices.
When the component bind fails multiple times this results in a
refcount_t overflow, as the reference count is never decremented:
fix that by adding a call to put_device() for all of the mmsys
devices in a loop, in error cases of mtk_drm_bind() and in the
mtk_drm_unbind() callback.
Fixes: 1ef7ed48356c ("drm/mediatek: Modify mediatek-drm for mt8195 multi mmsys support")
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/gpu/drm/mediatek/mtk_drm_drv.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index a8fbccb50c74..6b31df587507 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -676,6 +676,10 @@ static int mtk_drm_bind(struct device *dev)
for (i = 0; i < private->data->mmsys_dev_num; i++)
private->all_drm_private[i]->drm = NULL;
err_put_dev:
+ for (i = 0; i < private->data->mmsys_dev_num; i++) {
+ /* For device_find_child in mtk_drm_get_all_priv() */
+ put_device(private->all_drm_private[i]->dev);
+ }
put_device(private->mutex_dev);
return ret;
}
@@ -683,6 +687,7 @@ static int mtk_drm_bind(struct device *dev)
static void mtk_drm_unbind(struct device *dev)
{
struct mtk_drm_private *private = dev_get_drvdata(dev);
+ int i;
/* for multi mmsys dev, unregister drm dev in mmsys master */
if (private->drm_master) {
@@ -690,6 +695,10 @@ static void mtk_drm_unbind(struct device *dev)
mtk_drm_kms_deinit(private->drm);
drm_dev_put(private->drm);
+ for (i = 0; i < private->data->mmsys_dev_num; i++) {
+ /* For device_find_child in mtk_drm_get_all_priv() */
+ put_device(private->all_drm_private[i]->dev);
+ }
put_device(private->mutex_dev);
}
private->mtk_drm_bound = false;
--
2.48.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v1 3/5] drm/mediatek: mtk_drm_drv: Unbind secondary mmsys components on err
2025-04-02 8:36 [PATCH v1 0/5] drm/mediatek: Cleanups and sanitization AngeloGioacchino Del Regno
2025-04-02 8:36 ` [PATCH v1 1/5] drm/mediatek: mtk_drm_drv: Fix kobject put for mtk_mutex device ptr AngeloGioacchino Del Regno
2025-04-02 8:36 ` [PATCH v1 2/5] drm/mediatek: Fix kobject put for component sub-drivers AngeloGioacchino Del Regno
@ 2025-04-02 8:36 ` AngeloGioacchino Del Regno
2025-04-02 10:19 ` Chen-Yu Tsai
2025-04-02 8:36 ` [PATCH v1 4/5] drm/mediatek: mtk_disp_ovl: Enable/disable interrupt on bind/unbind AngeloGioacchino Del Regno
2025-04-02 8:36 ` [PATCH v1 5/5] drm/mediatek: mtk_disp_rdma: " AngeloGioacchino Del Regno
4 siblings, 1 reply; 12+ messages in thread
From: AngeloGioacchino Del Regno @ 2025-04-02 8:36 UTC (permalink / raw)
To: chunkuang.hu
Cc: p.zabel, airlied, simona, matthias.bgg,
angelogioacchino.delregno, nancy.lin, ck.hu, djkurtz, littlecvr,
bibby.hsieh, dri-devel, linux-mediatek, linux-kernel,
linux-arm-kernel, wenst, kernel
When calling component_bind_all(), if a component that is included
in the list fails, all of those that have been successfully bound
will be unbound, but this driver has two components lists for two
actual devices, as in, each mmsys instance has its own components
list.
In case mmsys0 (or actually vdosys0) is able to bind all of its
components, but the secondary one fails, all of the components of
the first are kept bound, while the ones of mmsys1/vdosys1 are
correctly cleaned up.
This is not right because, in case of a failure, the components
are re-bound for all of the mmsys/vdosys instances without caring
about the ones that were previously left in a bound state.
Fix that by calling component_unbind_all() on all of the previous
component masters that succeeded binding all subdevices when any
of the other masters errors out.
Fixes: 1ef7ed48356c ("drm/mediatek: Modify mediatek-drm for mt8195 multi mmsys support")
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/gpu/drm/mediatek/mtk_drm_drv.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 6b31df587507..2d6562b29755 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -482,8 +482,11 @@ static int mtk_drm_kms_init(struct drm_device *drm)
for (i = 0; i < private->data->mmsys_dev_num; i++) {
drm->dev_private = private->all_drm_private[i];
ret = component_bind_all(private->all_drm_private[i]->dev, drm);
- if (ret)
+ if (ret) {
+ while (--i >= 0)
+ component_unbind_all(private->all_drm_private[i]->dev, drm);
return ret;
+ }
}
/*
--
2.48.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v1 4/5] drm/mediatek: mtk_disp_ovl: Enable/disable interrupt on bind/unbind
2025-04-02 8:36 [PATCH v1 0/5] drm/mediatek: Cleanups and sanitization AngeloGioacchino Del Regno
` (2 preceding siblings ...)
2025-04-02 8:36 ` [PATCH v1 3/5] drm/mediatek: mtk_drm_drv: Unbind secondary mmsys components on err AngeloGioacchino Del Regno
@ 2025-04-02 8:36 ` AngeloGioacchino Del Regno
2025-04-02 9:38 ` Chen-Yu Tsai
2025-04-02 8:36 ` [PATCH v1 5/5] drm/mediatek: mtk_disp_rdma: " AngeloGioacchino Del Regno
4 siblings, 1 reply; 12+ messages in thread
From: AngeloGioacchino Del Regno @ 2025-04-02 8:36 UTC (permalink / raw)
To: chunkuang.hu
Cc: p.zabel, airlied, simona, matthias.bgg,
angelogioacchino.delregno, nancy.lin, ck.hu, djkurtz, littlecvr,
bibby.hsieh, dri-devel, linux-mediatek, linux-kernel,
linux-arm-kernel, wenst, kernel
The OVL driver is installing an ISR in the probe function but, if
the component is not bound yet, the interrupt handler may call the
vblank_cb ahead of time (while probing other drivers) or too late
(while removing other drivers), possibly accessing memory that it
should not try to access by reusing stale pointers.
In order to fix this, add a new `irq` member to struct mtk_disp_ovl
and then set the NOAUTOEN flag to the irq before installing the ISR
to manually call enable_irq() and disable_irq() in the bind and
unbind callbacks respectively.
Fixes: 119f5173628a ("drm/mediatek: Add DRM Driver for Mediatek SoC MT8173.")
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index df82cea4bb79..1bff3a1273f6 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -161,6 +161,7 @@ struct mtk_disp_ovl {
struct drm_crtc *crtc;
struct clk *clk;
void __iomem *regs;
+ int irq;
struct cmdq_client_reg cmdq_reg;
const struct mtk_disp_ovl_data *data;
void (*vblank_cb)(void *data);
@@ -587,12 +588,18 @@ void mtk_ovl_bgclr_in_off(struct device *dev)
static int mtk_disp_ovl_bind(struct device *dev, struct device *master,
void *data)
{
+ struct mtk_disp_ovl *priv = dev_get_drvdata(dev);
+
+ enable_irq(priv->irq);
return 0;
}
static void mtk_disp_ovl_unbind(struct device *dev, struct device *master,
void *data)
{
+ struct mtk_disp_ovl *priv = dev_get_drvdata(dev);
+
+ disable_irq(priv->irq);
}
static const struct component_ops mtk_disp_ovl_component_ops = {
@@ -605,16 +612,15 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct mtk_disp_ovl *priv;
struct resource *res;
- int irq;
int ret;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
- irq = platform_get_irq(pdev, 0);
- if (irq < 0)
- return irq;
+ priv->irq = platform_get_irq(pdev, 0);
+ if (priv->irq < 0)
+ return priv->irq;
priv->clk = devm_clk_get(dev, NULL);
if (IS_ERR(priv->clk))
@@ -635,10 +641,11 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
priv->data = of_device_get_match_data(dev);
platform_set_drvdata(pdev, priv);
- ret = devm_request_irq(dev, irq, mtk_disp_ovl_irq_handler,
+ irq_set_status_flags(priv->irq, IRQ_NOAUTOEN);
+ ret = devm_request_irq(dev, priv->irq, mtk_disp_ovl_irq_handler,
IRQF_TRIGGER_NONE, dev_name(dev), priv);
if (ret < 0)
- return dev_err_probe(dev, ret, "Failed to request irq %d\n", irq);
+ return dev_err_probe(dev, ret, "Failed to request irq %d\n", priv->irq);
pm_runtime_enable(dev);
--
2.48.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v1 5/5] drm/mediatek: mtk_disp_rdma: Enable/disable interrupt on bind/unbind
2025-04-02 8:36 [PATCH v1 0/5] drm/mediatek: Cleanups and sanitization AngeloGioacchino Del Regno
` (3 preceding siblings ...)
2025-04-02 8:36 ` [PATCH v1 4/5] drm/mediatek: mtk_disp_ovl: Enable/disable interrupt on bind/unbind AngeloGioacchino Del Regno
@ 2025-04-02 8:36 ` AngeloGioacchino Del Regno
2025-04-02 9:42 ` Chen-Yu Tsai
4 siblings, 1 reply; 12+ messages in thread
From: AngeloGioacchino Del Regno @ 2025-04-02 8:36 UTC (permalink / raw)
To: chunkuang.hu
Cc: p.zabel, airlied, simona, matthias.bgg,
angelogioacchino.delregno, nancy.lin, ck.hu, djkurtz, littlecvr,
bibby.hsieh, dri-devel, linux-mediatek, linux-kernel,
linux-arm-kernel, wenst, kernel
The RDMA driver is installing an ISR in the probe function but, if
the component is not bound yet, the interrupt handler may call the
vblank_cb ahead of time (while probing other drivers) or too late
(while removing other drivers), possibly accessing memory that it
should not try to access by reusing stale pointers.
In order to fix this, like done in the OVL driver, add a new `irq`
member to struct mtk_disp_ovl and then set the NOAUTOEN flag to
the irq before installing the ISR to manually disable and clear
the hwirqs with register writes, and enable_irq() and disable_irq()
in the bind and unbind callbacks respectively.
Fixes: 119f5173628a ("drm/mediatek: Add DRM Driver for Mediatek SoC MT8173.")
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/gpu/drm/mediatek/mtk_disp_rdma.c | 35 ++++++++++++++----------
1 file changed, 21 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
index bf47790e4d6b..8c5021365a04 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
@@ -81,6 +81,7 @@ struct mtk_disp_rdma_data {
struct mtk_disp_rdma {
struct clk *clk;
void __iomem *regs;
+ int irq;
struct cmdq_client_reg cmdq_reg;
const struct mtk_disp_rdma_data *data;
void (*vblank_cb)(void *data);
@@ -295,13 +296,23 @@ void mtk_rdma_layer_config(struct device *dev, unsigned int idx,
static int mtk_disp_rdma_bind(struct device *dev, struct device *master,
void *data)
{
- return 0;
+ struct mtk_disp_rdma *priv = dev_get_drvdata(dev);
+
+ /* Disable and clear pending interrupts */
+ writel(0x0, priv->regs + DISP_REG_RDMA_INT_ENABLE);
+ writel(0x0, priv->regs + DISP_REG_RDMA_INT_STATUS);
+ enable_irq(priv->irq);
+
+ return 0;
}
static void mtk_disp_rdma_unbind(struct device *dev, struct device *master,
void *data)
{
+ struct mtk_disp_rdma *priv = dev_get_drvdata(dev);
+
+ disable_irq(priv->irq);
}
static const struct component_ops mtk_disp_rdma_component_ops = {
@@ -314,16 +325,15 @@ static int mtk_disp_rdma_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct mtk_disp_rdma *priv;
struct resource *res;
- int irq;
int ret;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
- irq = platform_get_irq(pdev, 0);
- if (irq < 0)
- return irq;
+ priv->irq = platform_get_irq(pdev, 0);
+ if (priv->irq < 0)
+ return priv->irq;
priv->clk = devm_clk_get(dev, NULL);
if (IS_ERR(priv->clk))
@@ -347,21 +357,18 @@ static int mtk_disp_rdma_probe(struct platform_device *pdev)
if (ret && (ret != -EINVAL))
return dev_err_probe(dev, ret, "Failed to get rdma fifo size\n");
- /* Disable and clear pending interrupts */
- writel(0x0, priv->regs + DISP_REG_RDMA_INT_ENABLE);
- writel(0x0, priv->regs + DISP_REG_RDMA_INT_STATUS);
-
- ret = devm_request_irq(dev, irq, mtk_disp_rdma_irq_handler,
- IRQF_TRIGGER_NONE, dev_name(dev), priv);
- if (ret < 0)
- return dev_err_probe(dev, ret, "Failed to request irq %d\n", irq);
-
priv->data = of_device_get_match_data(dev);
platform_set_drvdata(pdev, priv);
pm_runtime_enable(dev);
+ irq_set_status_flags(priv->irq, IRQ_NOAUTOEN);
+ ret = devm_request_irq(dev, priv->irq, mtk_disp_rdma_irq_handler,
+ IRQF_TRIGGER_NONE, dev_name(dev), priv);
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "Failed to request irq %d\n", priv->irq);
+
ret = component_add(dev, &mtk_disp_rdma_component_ops);
if (ret) {
pm_runtime_disable(dev);
--
2.48.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v1 4/5] drm/mediatek: mtk_disp_ovl: Enable/disable interrupt on bind/unbind
2025-04-02 8:36 ` [PATCH v1 4/5] drm/mediatek: mtk_disp_ovl: Enable/disable interrupt on bind/unbind AngeloGioacchino Del Regno
@ 2025-04-02 9:38 ` Chen-Yu Tsai
2025-04-02 10:08 ` AngeloGioacchino Del Regno
0 siblings, 1 reply; 12+ messages in thread
From: Chen-Yu Tsai @ 2025-04-02 9:38 UTC (permalink / raw)
To: AngeloGioacchino Del Regno
Cc: chunkuang.hu, p.zabel, airlied, simona, matthias.bgg, nancy.lin,
ck.hu, djkurtz, littlecvr, bibby.hsieh, dri-devel,
linux-mediatek, linux-kernel, linux-arm-kernel, kernel
On Wed, Apr 2, 2025 at 4:36 PM AngeloGioacchino Del Regno
<angelogioacchino.delregno@collabora.com> wrote:
>
> The OVL driver is installing an ISR in the probe function but, if
> the component is not bound yet, the interrupt handler may call the
> vblank_cb ahead of time (while probing other drivers) or too late
> (while removing other drivers), possibly accessing memory that it
> should not try to access by reusing stale pointers.
>
> In order to fix this, add a new `irq` member to struct mtk_disp_ovl
> and then set the NOAUTOEN flag to the irq before installing the ISR
> to manually call enable_irq() and disable_irq() in the bind and
> unbind callbacks respectively.
>
> Fixes: 119f5173628a ("drm/mediatek: Add DRM Driver for Mediatek SoC MT8173.")
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> ---
> drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 19 +++++++++++++------
> 1 file changed, 13 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> index df82cea4bb79..1bff3a1273f6 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> @@ -161,6 +161,7 @@ struct mtk_disp_ovl {
> struct drm_crtc *crtc;
> struct clk *clk;
> void __iomem *regs;
> + int irq;
> struct cmdq_client_reg cmdq_reg;
> const struct mtk_disp_ovl_data *data;
> void (*vblank_cb)(void *data);
> @@ -587,12 +588,18 @@ void mtk_ovl_bgclr_in_off(struct device *dev)
> static int mtk_disp_ovl_bind(struct device *dev, struct device *master,
> void *data)
> {
> + struct mtk_disp_ovl *priv = dev_get_drvdata(dev);
> +
> + enable_irq(priv->irq);
> return 0;
> }
>
> static void mtk_disp_ovl_unbind(struct device *dev, struct device *master,
> void *data)
> {
> + struct mtk_disp_ovl *priv = dev_get_drvdata(dev);
> +
> + disable_irq(priv->irq);
> }
>
> static const struct component_ops mtk_disp_ovl_component_ops = {
> @@ -605,16 +612,15 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
> struct device *dev = &pdev->dev;
> struct mtk_disp_ovl *priv;
> struct resource *res;
> - int irq;
> int ret;
>
> priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> if (!priv)
> return -ENOMEM;
>
> - irq = platform_get_irq(pdev, 0);
> - if (irq < 0)
> - return irq;
> + priv->irq = platform_get_irq(pdev, 0);
> + if (priv->irq < 0)
> + return priv->irq;
>
> priv->clk = devm_clk_get(dev, NULL);
> if (IS_ERR(priv->clk))
> @@ -635,10 +641,11 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
> priv->data = of_device_get_match_data(dev);
> platform_set_drvdata(pdev, priv);
>
> - ret = devm_request_irq(dev, irq, mtk_disp_ovl_irq_handler,
> + irq_set_status_flags(priv->irq, IRQ_NOAUTOEN);
> + ret = devm_request_irq(dev, priv->irq, mtk_disp_ovl_irq_handler,
> IRQF_TRIGGER_NONE, dev_name(dev), priv);
Use IRQF_NO_AUTOEN here? Also, IRQF_TRIGGER_NONE can be dropped.
Make sense otherwise.
ChenYu
> if (ret < 0)
> - return dev_err_probe(dev, ret, "Failed to request irq %d\n", irq);
> + return dev_err_probe(dev, ret, "Failed to request irq %d\n", priv->irq);
>
> pm_runtime_enable(dev);
>
> --
> 2.48.1
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v1 5/5] drm/mediatek: mtk_disp_rdma: Enable/disable interrupt on bind/unbind
2025-04-02 8:36 ` [PATCH v1 5/5] drm/mediatek: mtk_disp_rdma: " AngeloGioacchino Del Regno
@ 2025-04-02 9:42 ` Chen-Yu Tsai
0 siblings, 0 replies; 12+ messages in thread
From: Chen-Yu Tsai @ 2025-04-02 9:42 UTC (permalink / raw)
To: AngeloGioacchino Del Regno
Cc: chunkuang.hu, p.zabel, airlied, simona, matthias.bgg, nancy.lin,
ck.hu, djkurtz, littlecvr, bibby.hsieh, dri-devel,
linux-mediatek, linux-kernel, linux-arm-kernel, kernel
On Wed, Apr 2, 2025 at 4:36 PM AngeloGioacchino Del Regno
<angelogioacchino.delregno@collabora.com> wrote:
>
> The RDMA driver is installing an ISR in the probe function but, if
> the component is not bound yet, the interrupt handler may call the
> vblank_cb ahead of time (while probing other drivers) or too late
> (while removing other drivers), possibly accessing memory that it
> should not try to access by reusing stale pointers.
>
> In order to fix this, like done in the OVL driver, add a new `irq`
> member to struct mtk_disp_ovl and then set the NOAUTOEN flag to
> the irq before installing the ISR to manually disable and clear
> the hwirqs with register writes, and enable_irq() and disable_irq()
> in the bind and unbind callbacks respectively.
>
> Fixes: 119f5173628a ("drm/mediatek: Add DRM Driver for Mediatek SoC MT8173.")
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> ---
> drivers/gpu/drm/mediatek/mtk_disp_rdma.c | 35 ++++++++++++++----------
> 1 file changed, 21 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> index bf47790e4d6b..8c5021365a04 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> @@ -81,6 +81,7 @@ struct mtk_disp_rdma_data {
> struct mtk_disp_rdma {
> struct clk *clk;
> void __iomem *regs;
> + int irq;
> struct cmdq_client_reg cmdq_reg;
> const struct mtk_disp_rdma_data *data;
> void (*vblank_cb)(void *data);
> @@ -295,13 +296,23 @@ void mtk_rdma_layer_config(struct device *dev, unsigned int idx,
> static int mtk_disp_rdma_bind(struct device *dev, struct device *master,
> void *data)
> {
> - return 0;
> + struct mtk_disp_rdma *priv = dev_get_drvdata(dev);
> +
> + /* Disable and clear pending interrupts */
> + writel(0x0, priv->regs + DISP_REG_RDMA_INT_ENABLE);
> + writel(0x0, priv->regs + DISP_REG_RDMA_INT_STATUS);
>
> + enable_irq(priv->irq);
> +
> + return 0;
> }
>
> static void mtk_disp_rdma_unbind(struct device *dev, struct device *master,
> void *data)
> {
> + struct mtk_disp_rdma *priv = dev_get_drvdata(dev);
> +
> + disable_irq(priv->irq);
> }
>
> static const struct component_ops mtk_disp_rdma_component_ops = {
> @@ -314,16 +325,15 @@ static int mtk_disp_rdma_probe(struct platform_device *pdev)
> struct device *dev = &pdev->dev;
> struct mtk_disp_rdma *priv;
> struct resource *res;
> - int irq;
> int ret;
>
> priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> if (!priv)
> return -ENOMEM;
>
> - irq = platform_get_irq(pdev, 0);
> - if (irq < 0)
> - return irq;
> + priv->irq = platform_get_irq(pdev, 0);
> + if (priv->irq < 0)
> + return priv->irq;
>
> priv->clk = devm_clk_get(dev, NULL);
> if (IS_ERR(priv->clk))
> @@ -347,21 +357,18 @@ static int mtk_disp_rdma_probe(struct platform_device *pdev)
> if (ret && (ret != -EINVAL))
> return dev_err_probe(dev, ret, "Failed to get rdma fifo size\n");
>
> - /* Disable and clear pending interrupts */
> - writel(0x0, priv->regs + DISP_REG_RDMA_INT_ENABLE);
> - writel(0x0, priv->regs + DISP_REG_RDMA_INT_STATUS);
> -
> - ret = devm_request_irq(dev, irq, mtk_disp_rdma_irq_handler,
> - IRQF_TRIGGER_NONE, dev_name(dev), priv);
> - if (ret < 0)
> - return dev_err_probe(dev, ret, "Failed to request irq %d\n", irq);
> -
> priv->data = of_device_get_match_data(dev);
>
> platform_set_drvdata(pdev, priv);
>
> pm_runtime_enable(dev);
>
> + irq_set_status_flags(priv->irq, IRQ_NOAUTOEN);
> + ret = devm_request_irq(dev, priv->irq, mtk_disp_rdma_irq_handler,
> + IRQF_TRIGGER_NONE, dev_name(dev), priv);
Same comment as OVL driver change.
ChenYu
> + if (ret < 0)
> + return dev_err_probe(dev, ret, "Failed to request irq %d\n", priv->irq);
> +
> ret = component_add(dev, &mtk_disp_rdma_component_ops);
> if (ret) {
> pm_runtime_disable(dev);
> --
> 2.48.1
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v1 4/5] drm/mediatek: mtk_disp_ovl: Enable/disable interrupt on bind/unbind
2025-04-02 9:38 ` Chen-Yu Tsai
@ 2025-04-02 10:08 ` AngeloGioacchino Del Regno
0 siblings, 0 replies; 12+ messages in thread
From: AngeloGioacchino Del Regno @ 2025-04-02 10:08 UTC (permalink / raw)
To: Chen-Yu Tsai
Cc: chunkuang.hu, p.zabel, airlied, simona, matthias.bgg, nancy.lin,
ck.hu, djkurtz, littlecvr, bibby.hsieh, dri-devel,
linux-mediatek, linux-kernel, linux-arm-kernel, kernel
Il 02/04/25 11:38, Chen-Yu Tsai ha scritto:
> On Wed, Apr 2, 2025 at 4:36 PM AngeloGioacchino Del Regno
> <angelogioacchino.delregno@collabora.com> wrote:
>>
>> The OVL driver is installing an ISR in the probe function but, if
>> the component is not bound yet, the interrupt handler may call the
>> vblank_cb ahead of time (while probing other drivers) or too late
>> (while removing other drivers), possibly accessing memory that it
>> should not try to access by reusing stale pointers.
>>
>> In order to fix this, add a new `irq` member to struct mtk_disp_ovl
>> and then set the NOAUTOEN flag to the irq before installing the ISR
>> to manually call enable_irq() and disable_irq() in the bind and
>> unbind callbacks respectively.
>>
>> Fixes: 119f5173628a ("drm/mediatek: Add DRM Driver for Mediatek SoC MT8173.")
>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
>> ---
>> drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 19 +++++++++++++------
>> 1 file changed, 13 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
>> index df82cea4bb79..1bff3a1273f6 100644
>> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
>> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
>> @@ -161,6 +161,7 @@ struct mtk_disp_ovl {
>> struct drm_crtc *crtc;
>> struct clk *clk;
>> void __iomem *regs;
>> + int irq;
>> struct cmdq_client_reg cmdq_reg;
>> const struct mtk_disp_ovl_data *data;
>> void (*vblank_cb)(void *data);
>> @@ -587,12 +588,18 @@ void mtk_ovl_bgclr_in_off(struct device *dev)
>> static int mtk_disp_ovl_bind(struct device *dev, struct device *master,
>> void *data)
>> {
>> + struct mtk_disp_ovl *priv = dev_get_drvdata(dev);
>> +
>> + enable_irq(priv->irq);
>> return 0;
>> }
>>
>> static void mtk_disp_ovl_unbind(struct device *dev, struct device *master,
>> void *data)
>> {
>> + struct mtk_disp_ovl *priv = dev_get_drvdata(dev);
>> +
>> + disable_irq(priv->irq);
>> }
>>
>> static const struct component_ops mtk_disp_ovl_component_ops = {
>> @@ -605,16 +612,15 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
>> struct device *dev = &pdev->dev;
>> struct mtk_disp_ovl *priv;
>> struct resource *res;
>> - int irq;
>> int ret;
>>
>> priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
>> if (!priv)
>> return -ENOMEM;
>>
>> - irq = platform_get_irq(pdev, 0);
>> - if (irq < 0)
>> - return irq;
>> + priv->irq = platform_get_irq(pdev, 0);
>> + if (priv->irq < 0)
>> + return priv->irq;
>>
>> priv->clk = devm_clk_get(dev, NULL);
>> if (IS_ERR(priv->clk))
>> @@ -635,10 +641,11 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
>> priv->data = of_device_get_match_data(dev);
>> platform_set_drvdata(pdev, priv);
>>
>> - ret = devm_request_irq(dev, irq, mtk_disp_ovl_irq_handler,
>> + irq_set_status_flags(priv->irq, IRQ_NOAUTOEN);
>> + ret = devm_request_irq(dev, priv->irq, mtk_disp_ovl_irq_handler,
>> IRQF_TRIGGER_NONE, dev_name(dev), priv);
>
> Use IRQF_NO_AUTOEN here? Also, IRQF_TRIGGER_NONE can be dropped.
>
Yeah, nice one. Thanks!
Cheers,
Angelo
> Make sense otherwise.
>
> ChenYu
>
>> if (ret < 0)
>> - return dev_err_probe(dev, ret, "Failed to request irq %d\n", irq);
>> + return dev_err_probe(dev, ret, "Failed to request irq %d\n", priv->irq);
>>
>> pm_runtime_enable(dev);
>>
>> --
>> 2.48.1
>>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v1 1/5] drm/mediatek: mtk_drm_drv: Fix kobject put for mtk_mutex device ptr
2025-04-02 8:36 ` [PATCH v1 1/5] drm/mediatek: mtk_drm_drv: Fix kobject put for mtk_mutex device ptr AngeloGioacchino Del Regno
@ 2025-04-02 10:14 ` Chen-Yu Tsai
0 siblings, 0 replies; 12+ messages in thread
From: Chen-Yu Tsai @ 2025-04-02 10:14 UTC (permalink / raw)
To: AngeloGioacchino Del Regno
Cc: chunkuang.hu, p.zabel, airlied, simona, matthias.bgg, nancy.lin,
ck.hu, djkurtz, littlecvr, bibby.hsieh, dri-devel,
linux-mediatek, linux-kernel, linux-arm-kernel, kernel
On Wed, Apr 2, 2025 at 4:36 PM AngeloGioacchino Del Regno
<angelogioacchino.delregno@collabora.com> wrote:
>
> This driver is taking a kobject for mtk_mutex only once per mmsys
> device for each drm-mediatek driver instance, differently from the
> behavior with other components, but it is decrementing the kobj's
> refcount in a loop and once per mmsys: this is not right and will
> result in a refcount_t underflow warning when mediatek-drm returns
> multiple probe deferrals in one boot (or when manually bound and
> unbound).
>
> Besides that, the refcount for mutex_dev was not decremented for
> error cases in mtk_drm_bind(), causing another refcount_t warning
> but this time for overflow, when the failure happens not during
> driver bind but during component bind.
>
> In order to fix one of the reasons why this is happening, remove
> the put_device(xx->mutex_dev) loop from the mtk_drm_kms_init()'s
> put_mutex_dev label (and drop the label) and add a single call to
> correctly free the single incremented refcount of mutex_dev to
> the mtk_drm_unbind() function to fix the refcount_t underflow.
>
> Moreover, add the same call to the error cases in mtk_drm_bind()
> to fix the refcount_t overflow.
>
> Fixes: 1ef7ed48356c ("drm/mediatek: Modify mediatek-drm for mt8195 multi mmsys support")
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
> ---
> drivers/gpu/drm/mediatek/mtk_drm_drv.c | 17 ++++++++++-------
> 1 file changed, 10 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index e09578756de0..a8fbccb50c74 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -464,7 +464,7 @@ static int mtk_drm_kms_init(struct drm_device *drm)
>
> ret = drmm_mode_config_init(drm);
> if (ret)
> - goto put_mutex_dev;
> + return ret;
>
> drm->mode_config.min_width = 64;
> drm->mode_config.min_height = 64;
> @@ -483,7 +483,7 @@ static int mtk_drm_kms_init(struct drm_device *drm)
> drm->dev_private = private->all_drm_private[i];
> ret = component_bind_all(private->all_drm_private[i]->dev, drm);
> if (ret)
> - goto put_mutex_dev;
> + return ret;
> }
>
> /*
> @@ -576,9 +576,6 @@ static int mtk_drm_kms_init(struct drm_device *drm)
> err_component_unbind:
> for (i = 0; i < private->data->mmsys_dev_num; i++)
> component_unbind_all(private->all_drm_private[i]->dev, drm);
> -put_mutex_dev:
> - for (i = 0; i < private->data->mmsys_dev_num; i++)
> - put_device(private->all_drm_private[i]->mutex_dev);
>
> return ret;
> }
> @@ -649,8 +646,10 @@ static int mtk_drm_bind(struct device *dev)
> return 0;
>
> drm = drm_dev_alloc(&mtk_drm_driver, dev);
> - if (IS_ERR(drm))
> - return PTR_ERR(drm);
> + if (IS_ERR(drm)) {
> + ret = PTR_ERR(drm);
> + goto err_put_dev;
> + }
>
> private->drm_master = true;
> drm->dev_private = private;
> @@ -676,6 +675,8 @@ static int mtk_drm_bind(struct device *dev)
> drm_dev_put(drm);
> for (i = 0; i < private->data->mmsys_dev_num; i++)
> private->all_drm_private[i]->drm = NULL;
> +err_put_dev:
> + put_device(private->mutex_dev);
> return ret;
> }
>
> @@ -688,6 +689,8 @@ static void mtk_drm_unbind(struct device *dev)
> drm_dev_unregister(private->drm);
> mtk_drm_kms_deinit(private->drm);
> drm_dev_put(private->drm);
> +
> + put_device(private->mutex_dev);
> }
> private->mtk_drm_bound = false;
> private->drm_master = false;
> --
> 2.48.1
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v1 2/5] drm/mediatek: Fix kobject put for component sub-drivers
2025-04-02 8:36 ` [PATCH v1 2/5] drm/mediatek: Fix kobject put for component sub-drivers AngeloGioacchino Del Regno
@ 2025-04-02 10:18 ` Chen-Yu Tsai
0 siblings, 0 replies; 12+ messages in thread
From: Chen-Yu Tsai @ 2025-04-02 10:18 UTC (permalink / raw)
To: AngeloGioacchino Del Regno
Cc: chunkuang.hu, p.zabel, airlied, simona, matthias.bgg, nancy.lin,
ck.hu, djkurtz, littlecvr, bibby.hsieh, dri-devel,
linux-mediatek, linux-kernel, linux-arm-kernel, kernel
On Wed, Apr 2, 2025 at 4:36 PM AngeloGioacchino Del Regno
<angelogioacchino.delregno@collabora.com> wrote:
>
> In function mtk_drm_get_all_priv(), this driver is incrementing
^ mtk_drm_get_all_drm_priv()
> the refcount for the sub-drivers of mediatek-drm with a call to
> device_find_child() when taking a reference to all of those child
> devices.
Looking closer, that function is also missing a platform_device_put()
to match of_find_device_by_node().
> When the component bind fails multiple times this results in a
> refcount_t overflow, as the reference count is never decremented:
> fix that by adding a call to put_device() for all of the mmsys
> devices in a loop, in error cases of mtk_drm_bind() and in the
> mtk_drm_unbind() callback.
>
> Fixes: 1ef7ed48356c ("drm/mediatek: Modify mediatek-drm for mt8195 multi mmsys support")
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
> ---
> drivers/gpu/drm/mediatek/mtk_drm_drv.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index a8fbccb50c74..6b31df587507 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -676,6 +676,10 @@ static int mtk_drm_bind(struct device *dev)
> for (i = 0; i < private->data->mmsys_dev_num; i++)
> private->all_drm_private[i]->drm = NULL;
> err_put_dev:
> + for (i = 0; i < private->data->mmsys_dev_num; i++) {
> + /* For device_find_child in mtk_drm_get_all_priv() */
> + put_device(private->all_drm_private[i]->dev);
> + }
> put_device(private->mutex_dev);
> return ret;
> }
> @@ -683,6 +687,7 @@ static int mtk_drm_bind(struct device *dev)
> static void mtk_drm_unbind(struct device *dev)
> {
> struct mtk_drm_private *private = dev_get_drvdata(dev);
> + int i;
>
> /* for multi mmsys dev, unregister drm dev in mmsys master */
> if (private->drm_master) {
> @@ -690,6 +695,10 @@ static void mtk_drm_unbind(struct device *dev)
> mtk_drm_kms_deinit(private->drm);
> drm_dev_put(private->drm);
>
> + for (i = 0; i < private->data->mmsys_dev_num; i++) {
Just FYI you can also declare the int within the for statement.
ChenYu
> + /* For device_find_child in mtk_drm_get_all_priv() */
> + put_device(private->all_drm_private[i]->dev);
> + }
> put_device(private->mutex_dev);
> }
> private->mtk_drm_bound = false;
> --
> 2.48.1
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v1 3/5] drm/mediatek: mtk_drm_drv: Unbind secondary mmsys components on err
2025-04-02 8:36 ` [PATCH v1 3/5] drm/mediatek: mtk_drm_drv: Unbind secondary mmsys components on err AngeloGioacchino Del Regno
@ 2025-04-02 10:19 ` Chen-Yu Tsai
0 siblings, 0 replies; 12+ messages in thread
From: Chen-Yu Tsai @ 2025-04-02 10:19 UTC (permalink / raw)
To: AngeloGioacchino Del Regno
Cc: chunkuang.hu, p.zabel, airlied, simona, matthias.bgg, nancy.lin,
ck.hu, djkurtz, littlecvr, bibby.hsieh, dri-devel,
linux-mediatek, linux-kernel, linux-arm-kernel, kernel
On Wed, Apr 2, 2025 at 4:36 PM AngeloGioacchino Del Regno
<angelogioacchino.delregno@collabora.com> wrote:
>
> When calling component_bind_all(), if a component that is included
> in the list fails, all of those that have been successfully bound
> will be unbound, but this driver has two components lists for two
> actual devices, as in, each mmsys instance has its own components
> list.
>
> In case mmsys0 (or actually vdosys0) is able to bind all of its
> components, but the secondary one fails, all of the components of
> the first are kept bound, while the ones of mmsys1/vdosys1 are
> correctly cleaned up.
>
> This is not right because, in case of a failure, the components
> are re-bound for all of the mmsys/vdosys instances without caring
> about the ones that were previously left in a bound state.
>
> Fix that by calling component_unbind_all() on all of the previous
> component masters that succeeded binding all subdevices when any
> of the other masters errors out.
>
> Fixes: 1ef7ed48356c ("drm/mediatek: Modify mediatek-drm for mt8195 multi mmsys support")
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Makes sense.
Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
> ---
> drivers/gpu/drm/mediatek/mtk_drm_drv.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index 6b31df587507..2d6562b29755 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -482,8 +482,11 @@ static int mtk_drm_kms_init(struct drm_device *drm)
> for (i = 0; i < private->data->mmsys_dev_num; i++) {
> drm->dev_private = private->all_drm_private[i];
> ret = component_bind_all(private->all_drm_private[i]->dev, drm);
> - if (ret)
> + if (ret) {
> + while (--i >= 0)
> + component_unbind_all(private->all_drm_private[i]->dev, drm);
> return ret;
> + }
> }
>
> /*
> --
> 2.48.1
>
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2025-04-02 10:19 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-04-02 8:36 [PATCH v1 0/5] drm/mediatek: Cleanups and sanitization AngeloGioacchino Del Regno
2025-04-02 8:36 ` [PATCH v1 1/5] drm/mediatek: mtk_drm_drv: Fix kobject put for mtk_mutex device ptr AngeloGioacchino Del Regno
2025-04-02 10:14 ` Chen-Yu Tsai
2025-04-02 8:36 ` [PATCH v1 2/5] drm/mediatek: Fix kobject put for component sub-drivers AngeloGioacchino Del Regno
2025-04-02 10:18 ` Chen-Yu Tsai
2025-04-02 8:36 ` [PATCH v1 3/5] drm/mediatek: mtk_drm_drv: Unbind secondary mmsys components on err AngeloGioacchino Del Regno
2025-04-02 10:19 ` Chen-Yu Tsai
2025-04-02 8:36 ` [PATCH v1 4/5] drm/mediatek: mtk_disp_ovl: Enable/disable interrupt on bind/unbind AngeloGioacchino Del Regno
2025-04-02 9:38 ` Chen-Yu Tsai
2025-04-02 10:08 ` AngeloGioacchino Del Regno
2025-04-02 8:36 ` [PATCH v1 5/5] drm/mediatek: mtk_disp_rdma: " AngeloGioacchino Del Regno
2025-04-02 9:42 ` Chen-Yu Tsai
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®