Skip to content

Commit 1f40369

Browse files
Ma KeChun-Kuang Hu
authored andcommitted
drm/mediatek: Fix device/node reference count leaks in mtk_drm_get_all_drm_priv
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'. Cc: stable@vger.kernel.org Fixes: 1ef7ed4 ("drm/mediatek: Modify mediatek-drm for mt8195 multi mmsys support") Signed-off-by: Ma Ke <make24@iscas.ac.cn> Reviewed-by: CK Hu <ck.hu@mediatek.com> Link: https://patchwork.kernel.org/project/dri-devel/patch/20250812071932.471730-1-make24@iscas.ac.cn/ Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
1 parent f5b1819 commit 1f40369

1 file changed

Lines changed: 14 additions & 7 deletions

File tree

drivers/gpu/drm/mediatek/mtk_drm_drv.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -387,19 +387,19 @@ static bool mtk_drm_get_all_drm_priv(struct device *dev)
387387

388388
of_id = of_match_node(mtk_drm_of_ids, node);
389389
if (!of_id)
390-
continue;
390+
goto next_put_node;
391391

392392
pdev = of_find_device_by_node(node);
393393
if (!pdev)
394-
continue;
394+
goto next_put_node;
395395

396396
drm_dev = device_find_child(&pdev->dev, NULL, mtk_drm_match);
397397
if (!drm_dev)
398-
continue;
398+
goto next_put_device_pdev_dev;
399399

400400
temp_drm_priv = dev_get_drvdata(drm_dev);
401401
if (!temp_drm_priv)
402-
continue;
402+
goto next_put_device_drm_dev;
403403

404404
if (temp_drm_priv->data->main_len)
405405
all_drm_priv[CRTC_MAIN] = temp_drm_priv;
@@ -411,10 +411,17 @@ static bool mtk_drm_get_all_drm_priv(struct device *dev)
411411
if (temp_drm_priv->mtk_drm_bound)
412412
cnt++;
413413

414-
if (cnt == MAX_CRTC) {
415-
of_node_put(node);
414+
next_put_device_drm_dev:
415+
put_device(drm_dev);
416+
417+
next_put_device_pdev_dev:
418+
put_device(&pdev->dev);
419+
420+
next_put_node:
421+
of_node_put(node);
422+
423+
if (cnt == MAX_CRTC)
416424
break;
417-
}
418425
}
419426

420427
if (drm_priv->data->mmsys_dev_num == cnt) {

0 commit comments

Comments
 (0)