Ma Ke <mak...@iscas.ac.cn> 於 2025年8月12日 週二 下午3:19寫道: > > Using device_find_child() and of_find_device_by_node() to locate > devices could cause an imbalance in the device's reference count. > device_find_child() and of_find_device_by_node() both call > get_device() to increment the reference count of the found device > before returning the pointer. In mtk_drm_get_all_drm_priv(), these > references are never released through put_device(), resulting in > permanent reference count increments. Additionally, the > for_each_child_of_node() iterator fails to release node references in > all code paths. This leaks device node references when loop > termination occurs before reaching MAX_CRTC. These reference count > leaks may prevent device/node resources from being properly released > during driver unbind operations. > > As comment of device_find_child() says, 'NOTE: you will need to drop > the reference with put_device() after use'. > > Found by code review.
Applied to mediatek-drm-fixes [1], thanks. [1] https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux.git/log/?h=mediatek-drm-fixes Regards, Chun-Kuang. > > Cc: sta...@vger.kernel.org > Fixes: 1ef7ed48356c ("drm/mediatek: Modify mediatek-drm for mt8195 multi > mmsys support") > Signed-off-by: Ma Ke <mak...@iscas.ac.cn> > --- > Changes in v2: > - added goto labels as suggestions. > --- > drivers/gpu/drm/mediatek/mtk_drm_drv.c | 21 ++++++++++++++------- > 1 file changed, 14 insertions(+), 7 deletions(-) > > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c > b/drivers/gpu/drm/mediatek/mtk_drm_drv.c > index d5e6bab36414..f8a817689e16 100644 > --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c > +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c > @@ -387,19 +387,19 @@ static bool mtk_drm_get_all_drm_priv(struct device *dev) > > of_id = of_match_node(mtk_drm_of_ids, node); > if (!of_id) > - continue; > + goto next_put_node; > > pdev = of_find_device_by_node(node); > if (!pdev) > - continue; > + goto next_put_node; > > drm_dev = device_find_child(&pdev->dev, NULL, mtk_drm_match); > if (!drm_dev) > - continue; > + goto next_put_device_pdev_dev; > > temp_drm_priv = dev_get_drvdata(drm_dev); > if (!temp_drm_priv) > - continue; > + goto next_put_device_drm_dev; > > if (temp_drm_priv->data->main_len) > all_drm_priv[CRTC_MAIN] = temp_drm_priv; > @@ -411,10 +411,17 @@ static bool mtk_drm_get_all_drm_priv(struct device *dev) > if (temp_drm_priv->mtk_drm_bound) > cnt++; > > - if (cnt == MAX_CRTC) { > - of_node_put(node); > +next_put_device_drm_dev: > + put_device(drm_dev); > + > +next_put_device_pdev_dev: > + put_device(&pdev->dev); > + > +next_put_node: > + of_node_put(node); > + > + if (cnt == MAX_CRTC) > break; > - } > } > > if (drm_priv->data->mmsys_dev_num == cnt) { > -- > 2.25.1 >