]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
scsi: pm80xx: Fix memory leak during rmmod
authorAjish Koshy <Ajish.Koshy@microchip.com>
Mon, 11 Aug 2025 05:20:35 +0000 (22:20 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 28 Aug 2025 14:22:55 +0000 (16:22 +0200)
[ Upstream commit 51e6ed83bb4ade7c360551fa4ae55c4eacea354b ]

Driver failed to release all memory allocated. This would lead to memory
leak during driver removal.

Properly free memory when the module is removed.

Link: https://lore.kernel.org/r/20210906170404.5682-5-Ajish.Koshy@microchip.com
Acked-by: Jack Wang <jinpu.wang@ionos.com>
Signed-off-by: Ajish Koshy <Ajish.Koshy@microchip.com>
Signed-off-by: Viswas G <Viswas.G@microchip.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
[Shivani: Modified to apply on 5.10.y]
Signed-off-by: Shivani Agarwal <shivani.agarwal@broadcom.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/scsi/pm8001/pm8001_init.c
drivers/scsi/pm8001/pm8001_sas.h

index f40db6f40b1dc876a136a22675ca6e099ef715ac..45bffa49f8766d934fdc9cfa9e5037259b312177 100644 (file)
@@ -1166,6 +1166,7 @@ pm8001_init_ccb_tag(struct pm8001_hba_info *pm8001_ha, struct Scsi_Host *shost,
                goto err_out;
 
        /* Memory region for ccb_info*/
+       pm8001_ha->ccb_count = ccb_count;
        pm8001_ha->ccb_info = (struct pm8001_ccb_info *)
                kcalloc(ccb_count, sizeof(struct pm8001_ccb_info), GFP_KERNEL);
        if (!pm8001_ha->ccb_info) {
@@ -1226,6 +1227,16 @@ static void pm8001_pci_remove(struct pci_dev *pdev)
                        tasklet_kill(&pm8001_ha->tasklet[j]);
 #endif
        scsi_host_put(pm8001_ha->shost);
+
+       for (i = 0; i < pm8001_ha->ccb_count; i++) {
+               dma_free_coherent(&pm8001_ha->pdev->dev,
+                       sizeof(struct pm8001_prd) * PM8001_MAX_DMA_SG,
+                       pm8001_ha->ccb_info[i].buf_prd,
+                       pm8001_ha->ccb_info[i].ccb_dma_handle);
+       }
+       kfree(pm8001_ha->ccb_info);
+       kfree(pm8001_ha->devices);
+
        pm8001_free(pm8001_ha);
        kfree(sha->sas_phy);
        kfree(sha->sas_port);
index 5cd6fe6a7d2d9fc02afd86f594ced032e2c9c2ee..74099d82e43649bd10e08ac9cdde6aeb3a2765b0 100644 (file)
@@ -515,6 +515,7 @@ struct pm8001_hba_info {
        u32                     iomb_size; /* SPC and SPCV IOMB size */
        struct pm8001_device    *devices;
        struct pm8001_ccb_info  *ccb_info;
+       u32                     ccb_count;
 #ifdef PM8001_USE_MSIX
        int                     number_of_intr;/*will be used in remove()*/
        char                    intr_drvname[PM8001_MAX_MSIX_VEC]