scsi: qla2xxx: Fix missed DMA unmap for NVMe ls requests
authorArun Easi <aeasi@marvell.com>
Thu, 10 Mar 2022 09:25:55 +0000 (01:25 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 8 Apr 2022 12:24:06 +0000 (14:24 +0200)
commit c85ab7d9e27a80e48d5b7d7fb2fe2b0fdb2de523 upstream.

At NVMe ELS request time, request structure is DMA mapped and never
unmapped. Fix this by calling the unmap on ELS completion.

Link: https://lore.kernel.org/r/20220310092604.22950-5-njavali@marvell.com
Fixes: e84067d74301 ("scsi: qla2xxx: Add FC-NVMe F/W initialization and transport registration")
Cc: stable@vger.kernel.org
Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
Signed-off-by: Arun Easi <aeasi@marvell.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/scsi/qla2xxx/qla_nvme.c

index 03aec9df0f9d36f187496951f2031fbd9d1c7d47..42b29f4fd93717f743179355c0798db5a3366cd4 100644 (file)
@@ -170,6 +170,18 @@ out:
        qla2xxx_rel_qpair_sp(sp->qpair, sp);
 }
 
+static void qla_nvme_ls_unmap(struct srb *sp, struct nvmefc_ls_req *fd)
+{
+       if (sp->flags & SRB_DMA_VALID) {
+               struct srb_iocb *nvme = &sp->u.iocb_cmd;
+               struct qla_hw_data *ha = sp->fcport->vha->hw;
+
+               dma_unmap_single(&ha->pdev->dev, nvme->u.nvme.cmd_dma,
+                                fd->rqstlen, DMA_TO_DEVICE);
+               sp->flags &= ~SRB_DMA_VALID;
+       }
+}
+
 static void qla_nvme_release_ls_cmd_kref(struct kref *kref)
 {
        struct srb *sp = container_of(kref, struct srb, cmd_kref);
@@ -186,6 +198,8 @@ static void qla_nvme_release_ls_cmd_kref(struct kref *kref)
        spin_unlock_irqrestore(&priv->cmd_lock, flags);
 
        fd = priv->fd;
+
+       qla_nvme_ls_unmap(sp, fd);
        fd->done(fd, priv->comp_status);
 out:
        qla2x00_rel_sp(sp);
@@ -356,6 +370,8 @@ static int qla_nvme_ls_req(struct nvme_fc_local_port *lport,
        dma_sync_single_for_device(&ha->pdev->dev, nvme->u.nvme.cmd_dma,
            fd->rqstlen, DMA_TO_DEVICE);
 
+       sp->flags |= SRB_DMA_VALID;
+
        rval = qla2x00_start_sp(sp);
        if (rval != QLA_SUCCESS) {
                ql_log(ql_log_warn, vha, 0x700e,
@@ -363,6 +379,7 @@ static int qla_nvme_ls_req(struct nvme_fc_local_port *lport,
                wake_up(&sp->nvme_ls_waitq);
                sp->priv = NULL;
                priv->sp = NULL;
+               qla_nvme_ls_unmap(sp, fd);
                qla2x00_rel_sp(sp);
                return rval;
        }