diff mbox series

scsi: ufs: ufshpb: Fix possible memory leak

Message ID 1891546521.01629427801384.JavaMail.epsvc@epcpadp3 (mailing list archive)
State Superseded
Headers show
Series scsi: ufs: ufshpb: Fix possible memory leak | expand

Commit Message

Keoseong Park Aug. 20, 2021, 1:46 a.m. UTC
When HPB pinned region exists and mctx allocation for this region fails,
memory leak is possible because memory is not released for the subregion
table of the current region.

So, change to free memory for the subregion table of the current region.

Signed-off-by: Keoseong Park <keosung.park@samsung.com>
---
 drivers/scsi/ufs/ufshpb.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

Comments

Bart Van Assche Aug. 20, 2021, 8:28 p.m. UTC | #1
On 8/19/21 6:46 PM, Keoseong Park wrote:
> When HPB pinned region exists and mctx allocation for this region fails,
> memory leak is possible because memory is not released for the subregion
> table of the current region.
> 
> So, change to free memory for the subregion table of the current region.
> 
> Signed-off-by: Keoseong Park <keosung.park@samsung.com>
> ---
>   drivers/scsi/ufs/ufshpb.c | 5 ++++-
>   1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c
> index 9acce92a356b..052f584c789a 100644
> --- a/drivers/scsi/ufs/ufshpb.c
> +++ b/drivers/scsi/ufs/ufshpb.c
> @@ -1933,7 +1933,7 @@ static int ufshpb_alloc_region_tbl(struct ufs_hba *hba, struct ufshpb_lu *hpb)
>   		if (ufshpb_is_pinned_region(hpb, rgn_idx)) {
>   			ret = ufshpb_init_pinned_active_region(hba, hpb, rgn);
>   			if (ret)
> -				goto release_srgn_table;
> +				goto release_current_srgn_table;
>   		} else {
>   			rgn->rgn_state = HPB_RGN_INACTIVE;
>   		}
> @@ -1944,6 +1944,9 @@ static int ufshpb_alloc_region_tbl(struct ufs_hba *hba, struct ufshpb_lu *hpb)
>   
>   	return 0;
>   
> +release_current_srgn_table:
> +	kvfree(rgn_table[rgn_idx].srgn_tbl);
> +
>   release_srgn_table:
>   	for (i = 0; i < rgn_idx; i++)
>   		kvfree(rgn_table[i].srgn_tbl);

'rgn_table' is allocated with kvcalloc() so please merge the new kvfree() statement
with the for-loop below it.

There is another improvement that can be made in this function: hpb->rgn_tbl
is not cleared in the error path. I propose to move the "hpb->rgn_tbl = rgn_table"
assignment from the start of the function to just above the "return 0" statement.

Thanks,

Bart.
Keoseong Park Aug. 23, 2021, 1:09 a.m. UTC | #2
Hi Bart,

> On 8/19/21 6:46 PM, Keoseong Park wrote:
>> When HPB pinned region exists and mctx allocation for this region fails,
>> memory leak is possible because memory is not released for the subregion
>> table of the current region.
>> 
>> So, change to free memory for the subregion table of the current region.
>> 
>> Signed-off-by: Keoseong Park <keosung.park@samsung.com>
>> ---
>>   drivers/scsi/ufs/ufshpb.c | 5 ++++-
>>   1 file changed, 4 insertions(+), 1 deletion(-)
>> 
>> diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c
>> index 9acce92a356b..052f584c789a 100644
>> --- a/drivers/scsi/ufs/ufshpb.c
>> +++ b/drivers/scsi/ufs/ufshpb.c
>> @@ -1933,7 +1933,7 @@ static int ufshpb_alloc_region_tbl(struct ufs_hba *hba, struct ufshpb_lu *hpb)
>>   		if (ufshpb_is_pinned_region(hpb, rgn_idx)) {
>>   			ret = ufshpb_init_pinned_active_region(hba, hpb, rgn);
>>   			if (ret)
>> -				goto release_srgn_table;
>> +				goto release_current_srgn_table;
>>   		} else {
>>   			rgn->rgn_state = HPB_RGN_INACTIVE;
>>   		}
>> @@ -1944,6 +1944,9 @@ static int ufshpb_alloc_region_tbl(struct ufs_hba *hba, struct ufshpb_lu *hpb)
>>   
>>   	return 0;
>>   
>> +release_current_srgn_table:
>> +	kvfree(rgn_table[rgn_idx].srgn_tbl);
>> +
>>   release_srgn_table:
>>   	for (i = 0; i < rgn_idx; i++)
>>   		kvfree(rgn_table[i].srgn_tbl);
>
>'rgn_table' is allocated with kvcalloc() so please merge the new kvfree() statement
>with the for-loop below it.
>
>There is another improvement that can be made in this function: hpb->rgn_tbl
>is not cleared in the error path. I propose to move the "hpb->rgn_tbl = rgn_table"
>assignment from the start of the function to just above the "return 0" statement.
>
>Thanks,
>
>Bart.
>

Thank you for your feedback.
I will fix it.

Best Regards,
Keoseong
diff mbox series

Patch

diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c
index 9acce92a356b..052f584c789a 100644
--- a/drivers/scsi/ufs/ufshpb.c
+++ b/drivers/scsi/ufs/ufshpb.c
@@ -1933,7 +1933,7 @@  static int ufshpb_alloc_region_tbl(struct ufs_hba *hba, struct ufshpb_lu *hpb)
 		if (ufshpb_is_pinned_region(hpb, rgn_idx)) {
 			ret = ufshpb_init_pinned_active_region(hba, hpb, rgn);
 			if (ret)
-				goto release_srgn_table;
+				goto release_current_srgn_table;
 		} else {
 			rgn->rgn_state = HPB_RGN_INACTIVE;
 		}
@@ -1944,6 +1944,9 @@  static int ufshpb_alloc_region_tbl(struct ufs_hba *hba, struct ufshpb_lu *hpb)
 
 	return 0;
 
+release_current_srgn_table:
+	kvfree(rgn_table[rgn_idx].srgn_tbl);
+
 release_srgn_table:
 	for (i = 0; i < rgn_idx; i++)
 		kvfree(rgn_table[i].srgn_tbl);