Skip to contentSkip to conversation

lpfc 8.3.0 : Fix some memory handling issues

PATCH In review James Smart 1 participant 1 message Dec 5, 2008

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 10/14 lpfc 8.3.0 : Fix some memory handling issues

lpfc 8.3.0 : Fix some memory handling issues

- Fix mailbox buffer leak on dump mailbox completion

- Fix mbuf leak in lpfc_pci_probe_one() SLI-2 mode error path

- Don't allocate HBQs in interrupt context

- Use correct size for FCP response buffer so that all available sense data is copied

- Fix jiffies calculation to prevent crash when collecting statistical data

---

 drivers/scsi/lpfc/lpfc_init.c |    7 +++-
 drivers/scsi/lpfc/lpfc_scsi.c |   14 +++++---
 drivers/scsi/lpfc/lpfc_sli.c  |   76 ++++-------------------------------------
 3 files changed, 23 insertions(+), 74 deletions(-)
drivers/scsi/lpfc/lpfc_init.c +6 -1
@@ -255,8 +255,10 @@ lpfc_dump_wakeup_param_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
 	/* character array used for decoding dist type. */
 	char dist_char[] = "nabx";
 
-	if (pmboxq->mb.mbxStatus != MBX_SUCCESS)
+	if (pmboxq->mb.mbxStatus != MBX_SUCCESS) {
+		mempool_free(pmboxq, phba->mbox_mem_pool);
 		return;
+	}
 
 	prg = (struct prog_id *) &prog_id_word;
 
@@ -274,6 +276,7 @@ lpfc_dump_wakeup_param_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
 		sprintf(phba->OptionROMVersion, "%d.%d%d%c%d",
 			prg->ver, prg->rev, prg->lev,
 			dist, prg->num);
+	mempool_free(pmboxq, phba->mbox_mem_pool);
 	return;
 }
 
@@ -2889,6 +2892,8 @@ out_remove_device:
 	lpfc_stop_phba_timers(phba);
 	phba->pport->work_port_events = 0;
 	lpfc_disable_intr(phba);
+	lpfc_sli_hba_down(phba);
+	lpfc_sli_brdrestart(phba);
 out_free_sysfs_attr:
 	lpfc_free_sysfs_attr(vport);
 out_destroy_port:
drivers/scsi/lpfc/lpfc_scsi.c +9 -5
@@ -66,6 +66,8 @@ lpfc_update_stats(struct lpfc_hba *phba, struct  lpfc_scsi_buf *lpfc_cmd)
 	if (cmd->result)
 		return;
 
+	latency = jiffies_to_msecs((long)jiffies - (long)lpfc_cmd->start_time);
+
 	spin_lock_irqsave(shost->host_lock, flags);
 	if (!vport->stat_data_enabled ||
 		vport->stat_data_blocked ||
@@ -74,13 +76,15 @@ lpfc_update_stats(struct lpfc_hba *phba, struct  lpfc_scsi_buf *lpfc_cmd)
 		spin_unlock_irqrestore(shost->host_lock, flags);
 		return;
 	}
-	latency = jiffies_to_msecs(jiffies - lpfc_cmd->start_time);
 
 	if (phba->bucket_type == LPFC_LINEAR_BUCKET) {
 		i = (latency + phba->bucket_step - 1 - phba->bucket_base)/
 			phba->bucket_step;
-		if (i >= LPFC_MAX_BUCKET_COUNT)
-			i = LPFC_MAX_BUCKET_COUNT;
+		/* check array subscript bounds */
+		if (i < 0)
+			i = 0;
+		else if (i >= LPFC_MAX_BUCKET_COUNT)
+			i = LPFC_MAX_BUCKET_COUNT - 1;
 	} else {
 		for (i = 0; i < LPFC_MAX_BUCKET_COUNT-1; i++)
 			if (latency <= (phba->bucket_base +
@@ -444,14 +448,14 @@ lpfc_new_scsi_buf(struct lpfc_vport *vport)
 	bpl[0].addrLow = le32_to_cpu(putPaddrLow(pdma_phys_fcp_cmd));
 	bpl[0].tus.f.bdeSize = sizeof(struct fcp_cmnd);
 	bpl[0].tus.f.bdeFlags = BUFF_TYPE_BDE_64;
-	bpl[0].tus.w = le32_to_cpu(bpl->tus.w);
+	bpl[0].tus.w = le32_to_cpu(bpl[0].tus.w);
 
 	/* Setup the physical region for the FCP RSP */
 	bpl[1].addrHigh = le32_to_cpu(putPaddrHigh(pdma_phys_fcp_rsp));
 	bpl[1].addrLow = le32_to_cpu(putPaddrLow(pdma_phys_fcp_rsp));
 	bpl[1].tus.f.bdeSize = sizeof(struct fcp_rsp);
 	bpl[1].tus.f.bdeFlags = BUFF_TYPE_BDE_64;
-	bpl[1].tus.w = le32_to_cpu(bpl->tus.w);
+	bpl[1].tus.w = le32_to_cpu(bpl[1].tus.w);
 
 	/*
 	 * Since the IOCB for the FCP I/O is built into this lpfc_scsi_buf,
drivers/scsi/lpfc/lpfc_sli.c +8 -68

97 lines not on this page · raw message