[PATCH v2] drm/amd/pp: Fix memory leak in error path in smumgr

Rex Zhu Rex.Zhu at amd.com
Wed Mar 14 10:12:15 UTC 2018


v2: not change the sequence of smu backend assignment

Free the backend structure if we fail to allocate device memory.

Change-Id: Ib2007d83f3d99dcc6c4a0c9fe9a9f144bb7469e9
Signed-off-by: Rex Zhu <Rex.Zhu at amd.com>
---
 drivers/gpu/drm/amd/powerplay/smumgr/cz_smumgr.c   | 32 ++++++++++++++--------
 drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c |  4 ++-
 .../gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c  |  4 ++-
 .../drm/amd/powerplay/smumgr/polaris10_smumgr.c    |  4 ++-
 drivers/gpu/drm/amd/powerplay/smumgr/rv_smumgr.c   | 18 +++++++-----
 .../gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c    |  4 ++-
 6 files changed, 43 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/cz_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/cz_smumgr.c
index 957739a..669c1be 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/cz_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/cz_smumgr.c
@@ -764,7 +764,7 @@ static int cz_smu_init(struct pp_hwmgr *hwmgr)
 				&cz_smu->toc_buffer.mc_addr,
 				&cz_smu->toc_buffer.kaddr);
 	if (ret)
-		return -EINVAL;
+		goto err2;
 
 	ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev,
 				cz_smu->smu_buffer.data_size,
@@ -773,19 +773,15 @@ static int cz_smu_init(struct pp_hwmgr *hwmgr)
 				&cz_smu->smu_buffer.handle,
 				&cz_smu->smu_buffer.mc_addr,
 				&cz_smu->smu_buffer.kaddr);
-	if (ret) {
-		amdgpu_bo_free_kernel(&cz_smu->toc_buffer.handle,
-					&cz_smu->toc_buffer.mc_addr,
-					&cz_smu->toc_buffer.kaddr);
-		return -EINVAL;
-	}
+	if (ret)
+		goto err1;
 
 	if (0 != cz_smu_populate_single_scratch_entry(hwmgr,
 		CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SCRATCH,
 		UCODE_ID_RLC_SCRATCH_SIZE_BYTE,
 		&cz_smu->scratch_buffer[cz_smu->scratch_buffer_length++])) {
 		pr_err("Error when Populate Firmware Entry.\n");
-		return -1;
+		goto err0;
 	}
 
 	if (0 != cz_smu_populate_single_scratch_entry(hwmgr,
@@ -793,14 +789,14 @@ static int cz_smu_init(struct pp_hwmgr *hwmgr)
 		UCODE_ID_RLC_SRM_ARAM_SIZE_BYTE,
 		&cz_smu->scratch_buffer[cz_smu->scratch_buffer_length++])) {
 		pr_err("Error when Populate Firmware Entry.\n");
-		return -1;
+		goto err0;
 	}
 	if (0 != cz_smu_populate_single_scratch_entry(hwmgr,
 		CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_DRAM,
 		UCODE_ID_RLC_SRM_DRAM_SIZE_BYTE,
 		&cz_smu->scratch_buffer[cz_smu->scratch_buffer_length++])) {
 		pr_err("Error when Populate Firmware Entry.\n");
-		return -1;
+		goto err0;
 	}
 
 	if (0 != cz_smu_populate_single_scratch_entry(hwmgr,
@@ -808,7 +804,7 @@ static int cz_smu_init(struct pp_hwmgr *hwmgr)
 		sizeof(struct SMU8_MultimediaPowerLogData),
 		&cz_smu->scratch_buffer[cz_smu->scratch_buffer_length++])) {
 		pr_err("Error when Populate Firmware Entry.\n");
-		return -1;
+		goto err0;
 	}
 
 	if (0 != cz_smu_populate_single_scratch_entry(hwmgr,
@@ -816,10 +812,22 @@ static int cz_smu_init(struct pp_hwmgr *hwmgr)
 		sizeof(struct SMU8_Fusion_ClkTable),
 		&cz_smu->scratch_buffer[cz_smu->scratch_buffer_length++])) {
 		pr_err("Error when Populate Firmware Entry.\n");
-		return -1;
+		goto err0;
 	}
 
 	return 0;
+
+err0:
+	amdgpu_bo_free_kernel(&cz_smu->smu_buffer.handle,
+				&cz_smu->smu_buffer.mc_addr,
+				&cz_smu->smu_buffer.kaddr);
+err1:
+	amdgpu_bo_free_kernel(&cz_smu->toc_buffer.handle,
+				&cz_smu->toc_buffer.mc_addr,
+				&cz_smu->toc_buffer.kaddr);
+err2:
+	kfree(cz_smu);
+	return -EINVAL;
 }
 
 static int cz_smu_fini(struct pp_hwmgr *hwmgr)
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c
index ed2e2e9..95fcda3 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c
@@ -354,8 +354,10 @@ static int fiji_smu_init(struct pp_hwmgr *hwmgr)
 
 	hwmgr->smu_backend = fiji_priv;
 
-	if (smu7_init(hwmgr))
+	if (smu7_init(hwmgr)) {
+		kfree(fiji_priv);
 		return -EINVAL;
+	}
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c
index 6255edf..4e2f62e 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c
@@ -271,8 +271,10 @@ static int iceland_smu_init(struct pp_hwmgr *hwmgr)
 
 	hwmgr->smu_backend = iceland_priv;
 
-	if (smu7_init(hwmgr))
+	if (smu7_init(hwmgr)) {
+		kfree(iceland_priv);
 		return -EINVAL;
+	}
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
index 0609acf..03ec1e5 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
@@ -349,8 +349,10 @@ static int polaris10_smu_init(struct pp_hwmgr *hwmgr)
 
 	hwmgr->smu_backend = smu_data;
 
-	if (smu7_init(hwmgr))
+	if (smu7_init(hwmgr)) {
+		kfree(smu_data);
 		return -EINVAL;
+	}
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/rv_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/rv_smumgr.c
index e2ee23a..1592cdd 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/rv_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/rv_smumgr.c
@@ -350,7 +350,7 @@ static int rv_smu_init(struct pp_hwmgr *hwmgr)
 			&kaddr);
 
 	if (r)
-		return -EINVAL;
+		goto err0;
 
 	priv->smu_tables.entry[WMTABLE].version = 0x01;
 	priv->smu_tables.entry[WMTABLE].size = sizeof(Watermarks_t);
@@ -368,12 +368,8 @@ static int rv_smu_init(struct pp_hwmgr *hwmgr)
 			&mc_addr,
 			&kaddr);
 
-	if (r) {
-		amdgpu_bo_free_kernel(&priv->smu_tables.entry[WMTABLE].handle,
-					&priv->smu_tables.entry[WMTABLE].mc_addr,
-					&priv->smu_tables.entry[WMTABLE].table);
-		return -EINVAL;
-	}
+	if (r)
+		goto err1;
 
 	priv->smu_tables.entry[CLOCKTABLE].version = 0x01;
 	priv->smu_tables.entry[CLOCKTABLE].size = sizeof(DpmClocks_t);
@@ -383,6 +379,14 @@ static int rv_smu_init(struct pp_hwmgr *hwmgr)
 	priv->smu_tables.entry[CLOCKTABLE].handle = handle;
 
 	return 0;
+
+err1:
+	amdgpu_bo_free_kernel(&priv->smu_tables.entry[WMTABLE].handle,
+				&priv->smu_tables.entry[WMTABLE].mc_addr,
+				&priv->smu_tables.entry[WMTABLE].table);
+err0:
+	kfree(priv);
+	return -EINVAL;
 }
 
 const struct pp_smumgr_func rv_smu_funcs = {
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c
index 39d6f4e..26cca8c 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c
@@ -229,8 +229,10 @@ static int tonga_smu_init(struct pp_hwmgr *hwmgr)
 
 	hwmgr->smu_backend = tonga_priv;
 
-	if (smu7_init(hwmgr))
+	if (smu7_init(hwmgr)) {
+		kfree(tonga_priv);
 		return -EINVAL;
+	}
 
 	return 0;
 }
-- 
1.9.1



More information about the amd-gfx mailing list