summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt3sas/mpt3sas_scsih.c
diff options
context:
space:
mode:
authorSreekanth Reddy <sreekanth.reddy@broadcom.com>2017-10-10 15:11:15 +0200
committerMartin K. Petersen <martin.petersen@oracle.com>2017-10-11 20:08:07 +0200
commitbbe3def3a11dc1040d45469f5dd26032e9fd8c79 (patch)
tree5756ec9dfa3aa282dda4dffdcd9386bea519ddd1 /drivers/scsi/mpt3sas/mpt3sas_scsih.c
parentscsi: mpt3sas: Processing of Cable Exception events (diff)
downloadlinux-bbe3def3a11dc1040d45469f5dd26032e9fd8c79.tar.xz
linux-bbe3def3a11dc1040d45469f5dd26032e9fd8c79.zip
scsi: mpt3sas: Fixed memory leaks in driver
While removing Expander devices, we are removing expander device entry from the list before freeing its child devices. While freeing child device we are finding its parent device node as NULL and therefore we are not freeing the child device's allocated data structures. Updated the driver to remove the expander device from the list only after freeing all its child devices. [mkp: clarified commit message] Signed-off-by: Sreekanth Reddy <Sreekanth.Reddy@broadcom.com> Reviewed-by: Tomas Henzl <thenzl@redhat.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/mpt3sas/mpt3sas_scsih.c')
-rw-r--r--drivers/scsi/mpt3sas/mpt3sas_scsih.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 73f30771ab1c..597fbecf001d 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -5274,8 +5274,6 @@ mpt3sas_expander_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address)
spin_lock_irqsave(&ioc->sas_node_lock, flags);
sas_expander = mpt3sas_scsih_expander_find_by_sas_address(ioc,
sas_address);
- if (sas_expander)
- list_del(&sas_expander->list);
spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
if (sas_expander)
_scsih_expander_node_remove(ioc, sas_expander);
@@ -7476,7 +7474,6 @@ _scsih_remove_unresponding_sas_devices(struct MPT3SAS_ADAPTER *ioc)
spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
list_for_each_entry_safe(sas_expander, sas_expander_next, &tmp_list,
list) {
- list_del(&sas_expander->list);
_scsih_expander_node_remove(ioc, sas_expander);
}
@@ -8102,7 +8099,6 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index,
* _scsih_expander_node_remove - removing expander device from list.
* @ioc: per adapter object
* @sas_expander: the sas_device object
- * Context: Calling function should acquire ioc->sas_node_lock.
*
* Removing object and freeing associated memory from the
* ioc->sas_expander_list.
@@ -8114,6 +8110,7 @@ _scsih_expander_node_remove(struct MPT3SAS_ADAPTER *ioc,
struct _sas_node *sas_expander)
{
struct _sas_port *mpt3sas_port, *next;
+ unsigned long flags;
/* remove sibling ports attached to this expander */
list_for_each_entry_safe(mpt3sas_port, next,
@@ -8141,6 +8138,10 @@ _scsih_expander_node_remove(struct MPT3SAS_ADAPTER *ioc,
sas_expander->handle, (unsigned long long)
sas_expander->sas_address);
+ spin_lock_irqsave(&ioc->sas_node_lock, flags);
+ list_del(&sas_expander->list);
+ spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
+
kfree(sas_expander->phy);
kfree(sas_expander);
}