Commit 027140ea authored by James Smart's avatar James Smart Committed by James Bottomley

[SCSI] lpfc 8.3.33: Misc changes to optimize critical path

Signed-off-by: default avatarJames Smart <james.smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 7e56aa25
...@@ -3919,6 +3919,8 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, ...@@ -3919,6 +3919,8 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
struct lpfc_iocbq *piocbq = &(lpfc_cmd->cur_iocbq); struct lpfc_iocbq *piocbq = &(lpfc_cmd->cur_iocbq);
int datadir = scsi_cmnd->sc_data_direction; int datadir = scsi_cmnd->sc_data_direction;
char tag[2]; char tag[2];
uint8_t *ptr;
bool sli4;
if (!pnode || !NLP_CHK_NODE_ACT(pnode)) if (!pnode || !NLP_CHK_NODE_ACT(pnode))
return; return;
...@@ -3930,8 +3932,13 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, ...@@ -3930,8 +3932,13 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
int_to_scsilun(lpfc_cmd->pCmd->device->lun, int_to_scsilun(lpfc_cmd->pCmd->device->lun,
&lpfc_cmd->fcp_cmnd->fcp_lun); &lpfc_cmd->fcp_cmnd->fcp_lun);
memset(&fcp_cmnd->fcpCdb[0], 0, LPFC_FCP_CDB_LEN); ptr = &fcp_cmnd->fcpCdb[0];
memcpy(&fcp_cmnd->fcpCdb[0], scsi_cmnd->cmnd, scsi_cmnd->cmd_len); memcpy(ptr, scsi_cmnd->cmnd, scsi_cmnd->cmd_len);
if (scsi_cmnd->cmd_len < LPFC_FCP_CDB_LEN) {
ptr += scsi_cmnd->cmd_len;
memset(ptr, 0, (LPFC_FCP_CDB_LEN - scsi_cmnd->cmd_len));
}
if (scsi_populate_tag_msg(scsi_cmnd, tag)) { if (scsi_populate_tag_msg(scsi_cmnd, tag)) {
switch (tag[0]) { switch (tag[0]) {
case HEAD_OF_QUEUE_TAG: case HEAD_OF_QUEUE_TAG:
...@@ -3947,6 +3954,8 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, ...@@ -3947,6 +3954,8 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
} else } else
fcp_cmnd->fcpCntl1 = 0; fcp_cmnd->fcpCntl1 = 0;
sli4 = (phba->sli_rev == LPFC_SLI_REV4);
/* /*
* There are three possibilities here - use scatter-gather segment, use * There are three possibilities here - use scatter-gather segment, use
* the single mapping, or neither. Start the lpfc command prep by * the single mapping, or neither. Start the lpfc command prep by
...@@ -3956,11 +3965,12 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, ...@@ -3956,11 +3965,12 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
if (scsi_sg_count(scsi_cmnd)) { if (scsi_sg_count(scsi_cmnd)) {
if (datadir == DMA_TO_DEVICE) { if (datadir == DMA_TO_DEVICE) {
iocb_cmd->ulpCommand = CMD_FCP_IWRITE64_CR; iocb_cmd->ulpCommand = CMD_FCP_IWRITE64_CR;
if (phba->sli_rev < LPFC_SLI_REV4) { if (sli4)
iocb_cmd->ulpPU = PARM_READ_CHECK;
else {
iocb_cmd->un.fcpi.fcpi_parm = 0; iocb_cmd->un.fcpi.fcpi_parm = 0;
iocb_cmd->ulpPU = 0; iocb_cmd->ulpPU = 0;
} else }
iocb_cmd->ulpPU = PARM_READ_CHECK;
fcp_cmnd->fcpCntl3 = WRITE_DATA; fcp_cmnd->fcpCntl3 = WRITE_DATA;
phba->fc4OutputRequests++; phba->fc4OutputRequests++;
} else { } else {
...@@ -3984,7 +3994,7 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, ...@@ -3984,7 +3994,7 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
* of the scsi_cmnd request_buffer * of the scsi_cmnd request_buffer
*/ */
piocbq->iocb.ulpContext = pnode->nlp_rpi; piocbq->iocb.ulpContext = pnode->nlp_rpi;
if (phba->sli_rev == LPFC_SLI_REV4) if (sli4)
piocbq->iocb.ulpContext = piocbq->iocb.ulpContext =
phba->sli4_hba.rpi_ids[pnode->nlp_rpi]; phba->sli4_hba.rpi_ids[pnode->nlp_rpi];
if (pnode->nlp_fcp_info & NLP_FCP_2_DEVICE) if (pnode->nlp_fcp_info & NLP_FCP_2_DEVICE)
......
...@@ -94,6 +94,7 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe *wqe) ...@@ -94,6 +94,7 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe *wqe)
union lpfc_wqe *temp_wqe; union lpfc_wqe *temp_wqe;
struct lpfc_register doorbell; struct lpfc_register doorbell;
uint32_t host_index; uint32_t host_index;
uint32_t idx;
/* sanity check on queue memory */ /* sanity check on queue memory */
if (unlikely(!q)) if (unlikely(!q))
...@@ -101,7 +102,8 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe *wqe) ...@@ -101,7 +102,8 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe *wqe)
temp_wqe = q->qe[q->host_index].wqe; temp_wqe = q->qe[q->host_index].wqe;
/* If the host has not yet processed the next entry then we are done */ /* If the host has not yet processed the next entry then we are done */
if (((q->host_index + 1) % q->entry_count) == q->hba_index) { idx = ((q->host_index + 1) % q->entry_count);
if (idx == q->hba_index) {
q->WQ_overflow++; q->WQ_overflow++;
return -ENOMEM; return -ENOMEM;
} }
...@@ -115,7 +117,8 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe *wqe) ...@@ -115,7 +117,8 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe *wqe)
/* Update the host index before invoking device */ /* Update the host index before invoking device */
host_index = q->host_index; host_index = q->host_index;
q->host_index = ((q->host_index + 1) % q->entry_count);
q->host_index = idx;
/* Ring Doorbell */ /* Ring Doorbell */
doorbell.word0 = 0; doorbell.word0 = 0;
...@@ -123,7 +126,6 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe *wqe) ...@@ -123,7 +126,6 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe *wqe)
bf_set(lpfc_wq_doorbell_index, &doorbell, host_index); bf_set(lpfc_wq_doorbell_index, &doorbell, host_index);
bf_set(lpfc_wq_doorbell_id, &doorbell, q->queue_id); bf_set(lpfc_wq_doorbell_id, &doorbell, q->queue_id);
writel(doorbell.word0, q->phba->sli4_hba.WQDBregaddr); writel(doorbell.word0, q->phba->sli4_hba.WQDBregaddr);
readl(q->phba->sli4_hba.WQDBregaddr); /* Flush */
return 0; return 0;
} }
...@@ -197,7 +199,6 @@ lpfc_sli4_mq_put(struct lpfc_queue *q, struct lpfc_mqe *mqe) ...@@ -197,7 +199,6 @@ lpfc_sli4_mq_put(struct lpfc_queue *q, struct lpfc_mqe *mqe)
bf_set(lpfc_mq_doorbell_num_posted, &doorbell, 1); bf_set(lpfc_mq_doorbell_num_posted, &doorbell, 1);
bf_set(lpfc_mq_doorbell_id, &doorbell, q->queue_id); bf_set(lpfc_mq_doorbell_id, &doorbell, q->queue_id);
writel(doorbell.word0, q->phba->sli4_hba.MQDBregaddr); writel(doorbell.word0, q->phba->sli4_hba.MQDBregaddr);
readl(q->phba->sli4_hba.MQDBregaddr); /* Flush */
return 0; return 0;
} }
...@@ -237,6 +238,7 @@ static struct lpfc_eqe * ...@@ -237,6 +238,7 @@ static struct lpfc_eqe *
lpfc_sli4_eq_get(struct lpfc_queue *q) lpfc_sli4_eq_get(struct lpfc_queue *q)
{ {
struct lpfc_eqe *eqe; struct lpfc_eqe *eqe;
uint32_t idx;
/* sanity check on queue memory */ /* sanity check on queue memory */
if (unlikely(!q)) if (unlikely(!q))
...@@ -247,10 +249,11 @@ lpfc_sli4_eq_get(struct lpfc_queue *q) ...@@ -247,10 +249,11 @@ lpfc_sli4_eq_get(struct lpfc_queue *q)
if (!bf_get_le32(lpfc_eqe_valid, eqe)) if (!bf_get_le32(lpfc_eqe_valid, eqe))
return NULL; return NULL;
/* If the host has not yet processed the next entry then we are done */ /* If the host has not yet processed the next entry then we are done */
if (((q->hba_index + 1) % q->entry_count) == q->host_index) idx = ((q->hba_index + 1) % q->entry_count);
if (idx == q->host_index)
return NULL; return NULL;
q->hba_index = ((q->hba_index + 1) % q->entry_count); q->hba_index = idx;
return eqe; return eqe;
} }
...@@ -321,6 +324,7 @@ static struct lpfc_cqe * ...@@ -321,6 +324,7 @@ static struct lpfc_cqe *
lpfc_sli4_cq_get(struct lpfc_queue *q) lpfc_sli4_cq_get(struct lpfc_queue *q)
{ {
struct lpfc_cqe *cqe; struct lpfc_cqe *cqe;
uint32_t idx;
/* sanity check on queue memory */ /* sanity check on queue memory */
if (unlikely(!q)) if (unlikely(!q))
...@@ -330,11 +334,12 @@ lpfc_sli4_cq_get(struct lpfc_queue *q) ...@@ -330,11 +334,12 @@ lpfc_sli4_cq_get(struct lpfc_queue *q)
if (!bf_get_le32(lpfc_cqe_valid, q->qe[q->hba_index].cqe)) if (!bf_get_le32(lpfc_cqe_valid, q->qe[q->hba_index].cqe))
return NULL; return NULL;
/* If the host has not yet processed the next entry then we are done */ /* If the host has not yet processed the next entry then we are done */
if (((q->hba_index + 1) % q->entry_count) == q->host_index) idx = ((q->hba_index + 1) % q->entry_count);
if (idx == q->host_index)
return NULL; return NULL;
cqe = q->qe[q->hba_index].cqe; cqe = q->qe[q->hba_index].cqe;
q->hba_index = ((q->hba_index + 1) % q->entry_count); q->hba_index = idx;
return cqe; return cqe;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment