FAILED: patch "[PATCH] drm/mediatek: Fix device/node reference count leaks in" failed to apply to 6.6-stable tree
Subsystems (4)
[email protected]
maintainerThe patch below does not apply to the 6.6-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.6.y
git checkout FETCH_HEAD
git cherry-pick -x 1f403699c40f0806a707a9a6eed3b8904224021a
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2025090146-playback-kinsman-373c@gregkh' --subject-prefix 'PATCH 6.6.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 1f403699c40f0806a707a9a6eed3b8904224021a Mon Sep 17 00:00:00 2001
From: Ma Ke <[email protected]>
Date: Tue, 12 Aug 2025 15:19:32 +0800
Subject: [PATCH] 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'.
drivers/gpu/drm/mediatek/mtk_drm_drv.c +14 -7
@@ -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) {
Sasha Levin
maintainerPATCH 1/3 drm/mediatek: Add crtc path enum for all_drm_priv array
From: "Jason-JH.Lin" <[email protected]>
[ Upstream commit 26c35d1d1646e593e3a82748b19d33b164871ae8 ]
Add mtk_drm_crtc_path enum for each display path.
Instead of using array index of all_drm_priv in mtk_drm_kms_init(), mtk_drm_crtc_path enum can make code more readable.
Stable-dep-of: 1f403699c40f ("drm/mediatek: Fix device/node reference count leaks in mtk_drm_get_all_drm_priv")
--- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 6 +++--- drivers/gpu/drm/mediatek/mtk_drm_drv.h | 8 +++++++- 2 files changed, 10 insertions(+), 4 deletions(-)
drivers/gpu/drm/mediatek/mtk_drm_drv.c +3 -3
@@ -475,21 +475,21 @@ static int mtk_drm_kms_init(struct drm_device *drm)for (j =0 ; j < private->data->mmsys_dev_num; j++) { priv_n = private->all_drm_private[j]; -if (i ==0 && priv_n->data->main_len) { +if (i ==CRTC_MAIN && priv_n->data->main_len) { ret =mtk_drm_crtc_create (drm, priv_n->data->main_path, priv_n->data->main_len, j);if (ret) goto err_component_unbind;continue ; - }else if (i ==1 && priv_n->data->ext_len) { + }else if (i ==CRTC_EXT && priv_n->data->ext_len) { ret =mtk_drm_crtc_create (drm, priv_n->data->ext_path, priv_n->data->ext_len, j);if (ret) goto err_component_unbind;continue ; - }else if (i ==2 && priv_n->data->third_len) { + }else if (i ==CRTC_THIRD && priv_n->data->third_len) { ret =mtk_drm_crtc_create (drm, priv_n->data->third_path, priv_n->data->third_len, j);if (ret)
drivers/gpu/drm/mediatek/mtk_drm_drv.h +7 -1
@@ -9,11 +9,17 @@#include <linux/io.h> #include "mtk_drm_ddp_comp.h" -#define MAX_CRTC 3#define MAX_CONNECTOR 2#define DDP_COMPONENT_DRM_OVL_ADAPTOR (DDP_COMPONENT_ID_MAX + 1)#define DDP_COMPONENT_DRM_ID_MAX (DDP_COMPONENT_DRM_OVL_ADAPTOR + 1) +enum mtk_drm_crtc_path { +CRTC_MAIN , +CRTC_EXT , +CRTC_THIRD , +MAX_CRTC , +}; +struct device ;struct device_node ;struct drm_crtc ;
Signature · 1 line
2.50.1
Sasha Levin
maintainerPATCH 2/3 drm/mediatek: Fix using wrong drm private data to bind mediatek-drm
From: "Jason-JH.Lin" <[email protected]>
[ Upstream commit ebba0960993045787ca00bb0932d83dad98c2e26 ]
According to mtk_drm_kms_init(), the all_drm_private array in each drm private data stores all drm private data in display path order.
In mtk_drm_get_all_drm_priv(), each element in all_drm_priv should have one display path private data, such as:
all_drm_priv[CRTC_MAIN] should only have main_path data all_drm_priv[CRTC_EXT] should only have ext_path data all_drm_priv[CRTC_THIRD] should only have third_path data
So we need to add the length checking for each display path before assigning their drm private data into all_drm_priv array.
Then the all_drm_private array in each drm private data needs to be assigned in their display path order.
Stable-dep-of: 1f403699c40f ("drm/mediatek: Fix device/node reference count leaks in mtk_drm_get_all_drm_priv")
--- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)
drivers/gpu/drm/mediatek/mtk_drm_drv.c +14 -3
@@ -352,6 +352,7 @@ static bool mtk_drm_get_all_drm_priv(struct device *dev) {struct mtk_drm_private *drm_priv =dev_get_drvdata (dev);struct mtk_drm_private *all_drm_priv[MAX_CRTC ]; +struct mtk_drm_private *temp_drm_priv;struct device_node *phandle = dev->parent->of_node;const struct of_device_id *of_id;struct device_node *node;
@@ -371,11 +372,21 @@ static bool mtk_drm_get_all_drm_priv(struct device *dev)continue ; drm_dev =device_find_child (&pdev->dev,NULL , mtk_drm_match); -if (!drm_dev || !dev_get_drvdata (drm_dev)) +if (!drm_dev)continue ; - all_drm_priv[cnt] =dev_get_drvdata (drm_dev); -if (all_drm_priv[cnt] && all_drm_priv[cnt]->mtk_drm_bound) + temp_drm_priv =dev_get_drvdata (drm_dev); +if (!temp_drm_priv) +continue ; + +if (temp_drm_priv->data->main_len) + all_drm_priv[CRTC_MAIN ] = temp_drm_priv; +else if (temp_drm_priv->data->ext_len) + all_drm_priv[CRTC_EXT ] = temp_drm_priv; +else if (temp_drm_priv->data->third_len) + all_drm_priv[CRTC_THIRD ] = temp_drm_priv; + +if (temp_drm_priv->mtk_drm_bound) cnt++;if (cnt ==MAX_CRTC ) {
Signature · 1 line
2.50.1
Sasha Levin
maintainerPATCH 3/3 drm/mediatek: Fix device/node reference count leaks in mtk_drm_get_all_drm_priv
In reply to Sasha LevinFrom: Ma Ke <[email protected]>
[ Upstream commit 1f403699c40f0806a707a9a6eed3b8904224021a ]
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'.
--- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-)
drivers/gpu/drm/mediatek/mtk_drm_drv.c +14 -7
@@ -365,19 +365,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;
@@ -389,10 +389,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) {
Signature · 1 line
2.50.1