aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_nvmet.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_nvmet.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_nvmet.c64
1 files changed, 41 insertions, 23 deletions
diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c
index 361e2b103648..d74bfd264495 100644
--- a/drivers/scsi/lpfc/lpfc_nvmet.c
+++ b/drivers/scsi/lpfc/lpfc_nvmet.c
@@ -220,7 +220,7 @@ lpfc_nvmet_cmd_template(void)
/* Word 12, 13, 14, 15 - is zero */
}
-void
+static void
lpfc_nvmet_defer_release(struct lpfc_hba *phba, struct lpfc_nvmet_rcv_ctx *ctxp)
{
lockdep_assert_held(&ctxp->ctxlock);
@@ -325,7 +325,6 @@ lpfc_nvmet_ctxbuf_post(struct lpfc_hba *phba, struct lpfc_nvmet_ctxbuf *ctx_buf)
struct fc_frame_header *fc_hdr;
struct rqb_dmabuf *nvmebuf;
struct lpfc_nvmet_ctx_info *infop;
- uint32_t *payload;
uint32_t size, oxid, sid;
int cpu;
unsigned long iflag;
@@ -370,7 +369,6 @@ lpfc_nvmet_ctxbuf_post(struct lpfc_hba *phba, struct lpfc_nvmet_ctxbuf *ctx_buf)
fc_hdr = (struct fc_frame_header *)(nvmebuf->hbuf.virt);
oxid = be16_to_cpu(fc_hdr->fh_ox_id);
tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
- payload = (uint32_t *)(nvmebuf->dbuf.virt);
size = nvmebuf->bytes_recv;
sid = sli4_sid_from_fc_hdr(fc_hdr);
@@ -435,7 +433,7 @@ lpfc_nvmet_ctxbuf_post(struct lpfc_hba *phba, struct lpfc_nvmet_ctxbuf *ctx_buf)
* Use the CPU context list, from the MRQ the IO was received on
* (ctxp->idx), to save context structure.
*/
- cpu = smp_processor_id();
+ cpu = raw_smp_processor_id();
infop = lpfc_get_ctx_list(phba, cpu, ctxp->idx);
spin_lock_irqsave(&infop->nvmet_ctx_list_lock, iflag);
list_add_tail(&ctx_buf->list, &infop->nvmet_ctx_list);
@@ -765,7 +763,7 @@ lpfc_nvmet_xmt_fcp_op_cmp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe,
}
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
if (phba->cpucheck_on & LPFC_CHECK_NVMET_IO) {
- id = smp_processor_id();
+ id = raw_smp_processor_id();
if (id < LPFC_CHECK_CPU_CNT) {
if (ctxp->cpu != id)
lpfc_printf_log(phba, KERN_INFO, LOG_NVME_IOERR,
@@ -906,7 +904,7 @@ lpfc_nvmet_xmt_fcp_op(struct nvmet_fc_target_port *tgtport,
ctxp->hdwq = &phba->sli4_hba.hdwq[rsp->hwqid];
if (phba->cpucheck_on & LPFC_CHECK_NVMET_IO) {
- int id = smp_processor_id();
+ int id = raw_smp_processor_id();
if (id < LPFC_CHECK_CPU_CNT) {
if (rsp->hwqid != id)
lpfc_printf_log(phba, KERN_INFO, LOG_NVME_IOERR,
@@ -1120,7 +1118,7 @@ lpfc_nvmet_defer_rcv(struct nvmet_fc_target_port *tgtport,
lpfc_nvmeio_data(phba, "NVMET DEFERRCV: xri x%x sz %d CPU %02x\n",
- ctxp->oxid, ctxp->size, smp_processor_id());
+ ctxp->oxid, ctxp->size, raw_smp_processor_id());
if (!nvmebuf) {
lpfc_printf_log(phba, KERN_INFO, LOG_NVME_IOERR,
@@ -1596,7 +1594,7 @@ lpfc_nvmet_rcv_unsol_abort(struct lpfc_vport *vport,
lpfc_nvmeio_data(phba,
"NVMET ABTS RCV: xri x%x CPU %02x rjt %d\n",
- xri, smp_processor_id(), 0);
+ xri, raw_smp_processor_id(), 0);
lpfc_printf_log(phba, KERN_INFO, LOG_NVME_ABTS,
"6319 NVMET Rcv ABTS:acc xri x%x\n", xri);
@@ -1612,7 +1610,7 @@ lpfc_nvmet_rcv_unsol_abort(struct lpfc_vport *vport,
spin_unlock_irqrestore(&phba->hbalock, iflag);
lpfc_nvmeio_data(phba, "NVMET ABTS RCV: xri x%x CPU %02x rjt %d\n",
- xri, smp_processor_id(), 1);
+ xri, raw_smp_processor_id(), 1);
lpfc_printf_log(phba, KERN_INFO, LOG_NVME_ABTS,
"6320 NVMET Rcv ABTS:rjt xri x%x\n", xri);
@@ -1725,7 +1723,11 @@ lpfc_nvmet_destroy_targetport(struct lpfc_hba *phba)
}
tgtp->tport_unreg_cmp = &tport_unreg_cmp;
nvmet_fc_unregister_targetport(phba->targetport);
- wait_for_completion_timeout(&tport_unreg_cmp, 5);
+ if (!wait_for_completion_timeout(tgtp->tport_unreg_cmp,
+ msecs_to_jiffies(LPFC_NVMET_WAIT_TMO)))
+ lpfc_printf_log(phba, KERN_ERR, LOG_NVME,
+ "6179 Unreg targetport %p timeout "
+ "reached.\n", phba->targetport);
lpfc_nvmet_cleanup_io_context(phba);
}
phba->targetport = NULL;
@@ -1843,7 +1845,7 @@ lpfc_nvmet_process_rcv_fcp_req(struct lpfc_nvmet_ctxbuf *ctx_buf)
struct lpfc_hba *phba = ctxp->phba;
struct rqb_dmabuf *nvmebuf = ctxp->rqb_buffer;
struct lpfc_nvmet_tgtport *tgtp;
- uint32_t *payload;
+ uint32_t *payload, qno;
uint32_t rc;
unsigned long iflags;
@@ -1876,6 +1878,15 @@ lpfc_nvmet_process_rcv_fcp_req(struct lpfc_nvmet_ctxbuf *ctx_buf)
/* Process FCP command */
if (rc == 0) {
atomic_inc(&tgtp->rcv_fcp_cmd_out);
+ spin_lock_irqsave(&ctxp->ctxlock, iflags);
+ if ((ctxp->flag & LPFC_NVMET_CTX_REUSE_WQ) ||
+ (nvmebuf != ctxp->rqb_buffer)) {
+ spin_unlock_irqrestore(&ctxp->ctxlock, iflags);
+ return;
+ }
+ ctxp->rqb_buffer = NULL;
+ spin_unlock_irqrestore(&ctxp->ctxlock, iflags);
+ lpfc_rq_buf_free(phba, &nvmebuf->hbuf); /* repost */
return;
}
@@ -1886,6 +1897,20 @@ lpfc_nvmet_process_rcv_fcp_req(struct lpfc_nvmet_ctxbuf *ctx_buf)
ctxp->oxid, ctxp->size, ctxp->sid);
atomic_inc(&tgtp->rcv_fcp_cmd_out);
atomic_inc(&tgtp->defer_fod);
+ spin_lock_irqsave(&ctxp->ctxlock, iflags);
+ if (ctxp->flag & LPFC_NVMET_CTX_REUSE_WQ) {
+ spin_unlock_irqrestore(&ctxp->ctxlock, iflags);
+ return;
+ }
+ spin_unlock_irqrestore(&ctxp->ctxlock, iflags);
+ /*
+ * Post a replacement DMA buffer to RQ and defer
+ * freeing rcv buffer till .defer_rcv callback
+ */
+ qno = nvmebuf->idx;
+ lpfc_post_rq_buffer(
+ phba, phba->sli4_hba.nvmet_mrq_hdr[qno],
+ phba->sli4_hba.nvmet_mrq_data[qno], 1, qno);
return;
}
atomic_inc(&tgtp->rcv_fcp_cmd_drop);
@@ -1996,7 +2021,6 @@ lpfc_nvmet_unsol_fcp_buffer(struct lpfc_hba *phba,
struct fc_frame_header *fc_hdr;
struct lpfc_nvmet_ctxbuf *ctx_buf;
struct lpfc_nvmet_ctx_info *current_infop;
- uint32_t *payload;
uint32_t size, oxid, sid, qno;
unsigned long iflag;
int current_cpu;
@@ -2020,7 +2044,7 @@ lpfc_nvmet_unsol_fcp_buffer(struct lpfc_hba *phba,
* be empty, thus it would need to be replenished with the
* context list from another CPU for this MRQ.
*/
- current_cpu = smp_processor_id();
+ current_cpu = raw_smp_processor_id();
current_infop = lpfc_get_ctx_list(phba, current_cpu, idx);
spin_lock_irqsave(&current_infop->nvmet_ctx_list_lock, iflag);
if (current_infop->nvmet_ctx_list_cnt) {
@@ -2050,7 +2074,7 @@ lpfc_nvmet_unsol_fcp_buffer(struct lpfc_hba *phba,
#endif
lpfc_nvmeio_data(phba, "NVMET FCP RCV: xri x%x sz %d CPU %02x\n",
- oxid, size, smp_processor_id());
+ oxid, size, raw_smp_processor_id());
tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
@@ -2074,7 +2098,6 @@ lpfc_nvmet_unsol_fcp_buffer(struct lpfc_hba *phba,
return;
}
- payload = (uint32_t *)(nvmebuf->dbuf.virt);
sid = sli4_sid_from_fc_hdr(fc_hdr);
ctxp = (struct lpfc_nvmet_rcv_ctx *)ctx_buf->context;
@@ -2690,12 +2713,11 @@ lpfc_nvmet_sol_fcp_abort_cmp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe,
{
struct lpfc_nvmet_rcv_ctx *ctxp;
struct lpfc_nvmet_tgtport *tgtp;
- uint32_t status, result;
+ uint32_t result;
unsigned long flags;
bool released = false;
ctxp = cmdwqe->context2;
- status = bf_get(lpfc_wcqe_c_status, wcqe);
result = wcqe->parameter;
tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
@@ -2761,11 +2783,10 @@ lpfc_nvmet_unsol_fcp_abort_cmp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe,
struct lpfc_nvmet_rcv_ctx *ctxp;
struct lpfc_nvmet_tgtport *tgtp;
unsigned long flags;
- uint32_t status, result;
+ uint32_t result;
bool released = false;
ctxp = cmdwqe->context2;
- status = bf_get(lpfc_wcqe_c_status, wcqe);
result = wcqe->parameter;
if (!ctxp) {
@@ -2842,10 +2863,9 @@ lpfc_nvmet_xmt_ls_abort_cmp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe,
{
struct lpfc_nvmet_rcv_ctx *ctxp;
struct lpfc_nvmet_tgtport *tgtp;
- uint32_t status, result;
+ uint32_t result;
ctxp = cmdwqe->context2;
- status = bf_get(lpfc_wcqe_c_status, wcqe);
result = wcqe->parameter;
tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
@@ -3200,7 +3220,6 @@ lpfc_nvmet_unsol_ls_issue_abort(struct lpfc_hba *phba,
{
struct lpfc_nvmet_tgtport *tgtp;
struct lpfc_iocbq *abts_wqeq;
- union lpfc_wqe128 *wqe_abts;
unsigned long flags;
int rc;
@@ -3230,7 +3249,6 @@ lpfc_nvmet_unsol_ls_issue_abort(struct lpfc_hba *phba,
}
}
abts_wqeq = ctxp->wqeq;
- wqe_abts = &abts_wqeq->wqe;
if (lpfc_nvmet_unsol_issue_abort(phba, ctxp, sid, xri) == 0) {
rc = WQE_BUSY;