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

Commit 1bfb3a07 authored by Varun Prakash's avatar Varun Prakash Committed by Greg Kroah-Hartman
Browse files

scsi: target: cxgbit: Unmap DMA buffer before calling target_execute_cmd()

commit 6ecdafaec79d4b3388a5b017245f23a0ff9d852d upstream.

Instead of calling dma_unmap_sg() after completing WRITE I/O, call
dma_unmap_sg() before calling target_execute_cmd() to sync the DMA buffer.

Link: https://lore.kernel.org/r/1618403949-3443-1-git-send-email-varun@chelsio.com


Cc: <stable@vger.kernel.org> # 5.4+
Signed-off-by: default avatarVarun Prakash <varun@chelsio.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 00d38f70
Loading
Loading
Loading
Loading
+10 −9
Original line number Diff line number Diff line
@@ -265,12 +265,13 @@ void cxgbit_unmap_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd)
	struct cxgbit_cmd *ccmd = iscsit_priv_cmd(cmd);

	if (ccmd->release) {
		struct cxgbi_task_tag_info *ttinfo = &ccmd->ttinfo;

		if (ttinfo->sgl) {
		if (cmd->se_cmd.se_cmd_flags & SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC) {
			put_page(sg_page(&ccmd->sg));
		} else {
			struct cxgbit_sock *csk = conn->context;
			struct cxgbit_device *cdev = csk->com.cdev;
			struct cxgbi_ppm *ppm = cdev2ppm(cdev);
			struct cxgbi_task_tag_info *ttinfo = &ccmd->ttinfo;

			/* Abort the TCP conn if DDP is not complete to
			 * avoid any possibility of DDP after freeing
@@ -280,14 +281,14 @@ void cxgbit_unmap_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd)
				     cmd->se_cmd.data_length))
				cxgbit_abort_conn(csk);

			cxgbi_ppm_ppod_release(ppm, ttinfo->idx);

			if (unlikely(ttinfo->sgl)) {
				dma_unmap_sg(&ppm->pdev->dev, ttinfo->sgl,
					     ttinfo->nents, DMA_FROM_DEVICE);
		} else {
			put_page(sg_page(&ccmd->sg));
				ttinfo->nents = 0;
				ttinfo->sgl = NULL;
			}
			cxgbi_ppm_ppod_release(ppm, ttinfo->idx);
		}

		ccmd->release = false;
	}
}
+18 −3
Original line number Diff line number Diff line
@@ -1013,17 +1013,18 @@ static int cxgbit_handle_iscsi_dataout(struct cxgbit_sock *csk)
	struct scatterlist *sg_start;
	struct iscsi_conn *conn = csk->conn;
	struct iscsi_cmd *cmd = NULL;
	struct cxgbit_cmd *ccmd;
	struct cxgbi_task_tag_info *ttinfo;
	struct cxgbit_lro_pdu_cb *pdu_cb = cxgbit_rx_pdu_cb(csk->skb);
	struct iscsi_data *hdr = (struct iscsi_data *)pdu_cb->hdr;
	u32 data_offset = be32_to_cpu(hdr->offset);
	u32 data_len = pdu_cb->dlen;
	u32 data_len = ntoh24(hdr->dlength);
	int rc, sg_nents, sg_off;
	bool dcrc_err = false;

	if (pdu_cb->flags & PDUCBF_RX_DDP_CMP) {
		u32 offset = be32_to_cpu(hdr->offset);
		u32 ddp_data_len;
		u32 payload_length = ntoh24(hdr->dlength);
		bool success = false;

		cmd = iscsit_find_cmd_from_itt_or_dump(conn, hdr->itt, 0);
@@ -1038,7 +1039,7 @@ static int cxgbit_handle_iscsi_dataout(struct cxgbit_sock *csk)
		cmd->data_sn = be32_to_cpu(hdr->datasn);

		rc = __iscsit_check_dataout_hdr(conn, (unsigned char *)hdr,
						cmd, payload_length, &success);
						cmd, data_len, &success);
		if (rc < 0)
			return rc;
		else if (!success)
@@ -1076,6 +1077,20 @@ static int cxgbit_handle_iscsi_dataout(struct cxgbit_sock *csk)
		cxgbit_skb_copy_to_sg(csk->skb, sg_start, sg_nents, skip);
	}

	ccmd = iscsit_priv_cmd(cmd);
	ttinfo = &ccmd->ttinfo;

	if (ccmd->release && ttinfo->sgl &&
	    (cmd->se_cmd.data_length ==	(cmd->write_data_done + data_len))) {
		struct cxgbit_device *cdev = csk->com.cdev;
		struct cxgbi_ppm *ppm = cdev2ppm(cdev);

		dma_unmap_sg(&ppm->pdev->dev, ttinfo->sgl, ttinfo->nents,
			     DMA_FROM_DEVICE);
		ttinfo->nents = 0;
		ttinfo->sgl = NULL;
	}

check_payload:

	rc = iscsit_check_dataout_payload(cmd, hdr, dcrc_err);