Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1dcb58e5 authored by James Smart's avatar James Smart Committed by James Bottomley
Browse files

[SCSI] lpfc 8.1.12 : Misc bug fixes and code cleanup



Misc bug fixes and code cleanup:
 - Fix system hang while running on systems with IOMMU
 - Fix use after free issues with rports
 - Don't free mailbox structure if it's still on the mboxq list
 - Decrement txq_cnt rather than txcmplq_cnt when parsing the txq list
 - Use msleep for long delays to prevent soft lockup bug check
 - Don't remove node during dev_loss_tmo if discovery is active
 - Fix memory leaks in get/reset statistics and link attention paths
 - Fixed lpfc_ns_rsp to handle entire GID_FT response.
 - mbox interface should use MAILBOX_CMD_SIZE rather than sizeof(MAILBOX_t)
 - Fixed bug check in add_timer.
 - Fixup messages 0116, 0117, and 0128 to report ELS I/O tag.
 - Remove unused parameter to lpfc_cleanup.
 - Change mailbox timeout handling.
 - Remove unused buflist. Code cleanup.

Signed-off-by: default avatarJames Smart <James.Smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent e555db93
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -387,9 +387,6 @@ struct lpfc_hba {

	mempool_t *mbox_mem_pool;
	mempool_t *nlp_mem_pool;
	struct list_head freebufList;
	struct list_head ctrspbuflist;
	struct list_head rnidrspbuflist;

	struct fc_host_statistics link_stats;
};
+14 −5
Original line number Diff line number Diff line
@@ -1227,11 +1227,11 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
	int rc;

	if (off > sizeof(MAILBOX_t))
	if (off > MAILBOX_CMD_SIZE)
		return -ERANGE;

	if ((count + off) > sizeof(MAILBOX_t))
		count = sizeof(MAILBOX_t) - off;
	if ((count + off) > MAILBOX_CMD_SIZE)
		count = MAILBOX_CMD_SIZE - off;

	if (off % 4 ||  count % 4 || (unsigned long)buf % 4)
		return -EINVAL;
@@ -1326,6 +1326,11 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
		}

		if (rc != MBX_SUCCESS) {
			if (rc == MBX_TIMEOUT) {
				phba->sysfs_mbox.mbox->mbox_cmpl =
					lpfc_sli_def_mbox_cmpl;
				phba->sysfs_mbox.mbox = NULL;
			}
			sysfs_mbox_idle(phba);
			spin_unlock_irq(host->host_lock);
			return  (rc == MBX_TIMEOUT) ? -ETIME : -ENODEV;
@@ -1344,7 +1349,7 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count)

	phba->sysfs_mbox.offset = off + count;

	if (phba->sysfs_mbox.offset == sizeof(MAILBOX_t))
	if (phba->sysfs_mbox.offset == MAILBOX_CMD_SIZE)
		sysfs_mbox_idle(phba);

	spin_unlock_irq(phba->host->host_lock);
@@ -1358,7 +1363,7 @@ static struct bin_attribute sysfs_mbox_attr = {
		.mode = S_IRUSR | S_IWUSR,
		.owner = THIS_MODULE,
	},
	.size = sizeof(MAILBOX_t),
	.size = MAILBOX_CMD_SIZE,
	.read = sysfs_mbox_read,
	.write = sysfs_mbox_write,
};
@@ -1631,6 +1636,8 @@ lpfc_get_stats(struct Scsi_Host *shost)
	else
		hs->seconds_since_last_reset = seconds - psli->stats_start;

	mempool_free(pmboxq, phba->mbox_mem_pool);

	return hs;
}

@@ -1699,6 +1706,8 @@ lpfc_reset_stats(struct Scsi_Host *shost)

	psli->stats_start = get_seconds();

	mempool_free(pmboxq, phba->mbox_mem_pool);

	return;
}

+3 −2
Original line number Diff line number Diff line
@@ -342,9 +342,10 @@ lpfc_ns_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mp, uint32_t Size)

		Size -= Cnt;

		if (!ctptr)
		if (!ctptr) {
			Cnt = FCELSSIZE;
			ctptr = (uint32_t *) mlast->virt;
		else
		} else
			Cnt -= 16;	/* subtract length of CT header */

		/* Loop through entire NameServer list of DIDs */
+8 −9
Original line number Diff line number Diff line
@@ -222,16 +222,16 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp,
		/* Xmit ELS command <elsCmd> to remote NPORT <did> */
		lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
				"%d:0116 Xmit ELS command x%x to remote "
				"NPORT x%x Data: x%x x%x\n",
				"NPORT x%x I/O tag: x%x, HBA state: x%x\n",
				phba->brd_no, elscmd,
				did, icmd->ulpIoTag, phba->hba_state);
				did, elsiocb->iotag, phba->hba_state);
	} else {
		/* Xmit ELS response <elsCmd> to remote NPORT <did> */
		lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
				"%d:0117 Xmit ELS response x%x to remote "
				"NPORT x%x Data: x%x x%x\n",
				"NPORT x%x I/O tag: x%x, size: x%x\n",
				phba->brd_no, elscmd,
				ndlp->nlp_DID, icmd->ulpIoTag, cmdSize);
				ndlp->nlp_DID, elsiocb->iotag, cmdSize);
	}

	return elsiocb;
@@ -2017,10 +2017,9 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag,

	/* Xmit ELS ACC response tag <ulpIoTag> */
	lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
			"%d:0128 Xmit ELS ACC response tag x%x "
			"Data: x%x x%x x%x x%x x%x\n",
			phba->brd_no,
			elsiocb->iocb.ulpIoTag,
			"%d:0128 Xmit ELS ACC response tag x%x, XRI: x%x, "
			"DID: x%x, nlp_flag: x%x nlp_state: x%x RPI: x%x\n",
			phba->brd_no, elsiocb->iotag,
			elsiocb->iocb.ulpContext, ndlp->nlp_DID,
			ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);

@@ -3363,7 +3362,7 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba)
		els_command = *elscmd;

		list_del(&piocb->list);
		pring->txcmplq_cnt--;
		pring->txq_cnt--;

		cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
		cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
+15 −14
Original line number Diff line number Diff line
@@ -147,11 +147,14 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
				ndlp->nlp_state, ndlp->nlp_rpi);
	}

	ndlp->rport = NULL;
	rdata->pnode = NULL;

	if (!(phba->fc_flag & FC_UNLOADING))
	if (!(phba->fc_flag & FC_UNLOADING) &&
	    !(ndlp->nlp_flag & NLP_DELAY_TMO) &&
	    !(ndlp->nlp_flag & NLP_NPR_2B_DISC))
		lpfc_disc_state_machine(phba, ndlp, NULL, NLP_EVT_DEVICE_RM);
	else {
		rdata->pnode = NULL;
		ndlp->rport = NULL;
	}

	return;
}
@@ -1569,16 +1572,6 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)

	lpfc_nlp_list(phba, ndlp, NLP_JUST_DQ);

	/*
	 * if unloading the driver - just leave the remote port in place.
	 * The driver unload will force the attached devices to detach
	 * and flush cache's w/o generating flush errors.
	 */
	if ((ndlp->rport) && !(phba->fc_flag & FC_UNLOADING)) {
		lpfc_unregister_remote_port(phba, ndlp);
		ndlp->nlp_sid = NLP_NO_SID;
	}

	/* cleanup any ndlp on mbox q waiting for reglogin cmpl */
	if ((mb = phba->sli.mbox_active)) {
		if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) &&
@@ -1627,6 +1620,7 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
int
lpfc_nlp_remove(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
{
	struct lpfc_rport_data *rdata;

	if (ndlp->nlp_flag & NLP_DELAY_TMO) {
		lpfc_cancel_retry_delay_tmo(phba, ndlp);
@@ -1638,6 +1632,13 @@ lpfc_nlp_remove(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
		spin_unlock_irq(phba->host->host_lock);
	} else {
		lpfc_freenode(phba, ndlp);

		if ((ndlp->rport) && !(phba->fc_flag & FC_UNLOADING)) {
			rdata = ndlp->rport->dd_data;
			rdata->pnode = NULL;
			ndlp->rport = NULL;
		}

		mempool_free( ndlp, phba->nlp_mem_pool);
	}
	return 0;
Loading