[openib-general] [PATCH] SRP: don't use TX IU after freeing it

Roland Dreier rolandd at cisco.com
Wed Sep 28 21:59:50 PDT 2005


Vu, you pointed out that the current SRP code might look at an IU that
it sent after that IU has been reused for a different command.  I
realized that a simple fix for this is just to keep the DMA address
(the only thing we look at in the IU) in the request structure.

To add FMR support, we can just put all the FMR stuff in the request
structure instead of the IU structure.  This saves bloating the IUs we
use for receives and task management, so it seems like a win anyway.

Does this patch seem OK and work for you?  It works for me in my setup.

 - R.

--- linux-kernel/infiniband/ulp/srp/ib_srp.c	(revision 3613)
+++ linux-kernel/infiniband/ulp/srp/ib_srp.c	(working copy)
@@ -523,9 +523,9 @@ err:
 }
 
 static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target,
-			struct srp_iu *iu)
+			struct srp_request *req)
 {
-	struct srp_cmd *cmd = iu->buf;
+	struct srp_cmd *cmd = req->cmd->buf;
 	int len;
 	u8 fmt;
 
@@ -569,7 +569,7 @@ static int srp_map_data(struct scsi_cmnd
 			else
 				cmd->data_in_desc_cnt = n;
 
-			buf->table_desc.va  = cpu_to_be64(iu->dma +
+			buf->table_desc.va  = cpu_to_be64(req->cmd->dma +
 							  sizeof *cmd +
 							  sizeof *buf);
 			buf->table_desc.key =
@@ -606,6 +606,8 @@ static int srp_map_data(struct scsi_cmnd
 			return -EINVAL;
 		}
 
+		pci_unmap_addr_set(req, direct_mapping, dma);
+
 		buf->va  = cpu_to_be64(dma);
 		buf->key = cpu_to_be32(target->srp_host->mr->rkey);
 		buf->len = cpu_to_be32(scmnd->request_bufflen);
@@ -626,7 +628,7 @@ static int srp_map_data(struct scsi_cmnd
 
 static void srp_unmap_data(struct scsi_cmnd *scmnd,
 			   struct srp_target_port *target,
-			   struct srp_cmd *cmd)
+			   struct srp_request *req)
 {
 	if (!scmnd->request_buffer ||
 	    (scmnd->sc_data_direction != DMA_TO_DEVICE &&
@@ -639,7 +641,7 @@ static void srp_unmap_data(struct scsi_c
 			     scmnd->use_sg, scmnd->sc_data_direction);
 	else
 		dma_unmap_single(target->srp_host->dev->dma_device,
-				 be64_to_cpu(((struct srp_direct_buf *) cmd->add_data)->va),
+				 pci_unmap_addr(req, direct_mapping),
 				 scmnd->request_bufflen,
 				 scmnd->sc_data_direction);
 }
@@ -648,7 +650,6 @@ static void srp_process_rsp(struct srp_t
 {
 	struct srp_request *req;
 	struct scsi_cmnd *scmnd;
-	struct srp_iu *iu;
 	unsigned long flags;
 	s32 delta;
 
@@ -667,7 +668,6 @@ static void srp_process_rsp(struct srp_t
 			req->tsk_status = rsp->data[3];
 		complete(&req->done);
 	} else {
-		iu 	      = req->cmd;
 		scmnd 	      = req->scmnd;
 		scmnd->result = rsp->status;
 
@@ -683,7 +683,7 @@ static void srp_process_rsp(struct srp_t
 		else if (rsp->flags & (SRP_RSP_FLAG_DIOVER | SRP_RSP_FLAG_DIUNDER))
 			scmnd->resid = be32_to_cpu(rsp->data_in_res_cnt);
 
-		srp_unmap_data(scmnd, target, iu->buf);
+		srp_unmap_data(scmnd, target, req);
 
 		if (!req->tsk_mgmt) {
 			req->scmnd = NULL;
@@ -919,7 +919,7 @@ static int srp_queuecommand(struct scsi_
 	req->cmd_done = 0;
 	req->tsk_mgmt = NULL;
 
-	len = srp_map_data(scmnd, target, iu);
+	len = srp_map_data(scmnd, target, req);
 	if (len < 0) {
 		printk(KERN_ERR PFX "Failed to map data\n");
 		goto err;
@@ -944,7 +944,7 @@ static int srp_queuecommand(struct scsi_
 	return 0;
 
 err_unmap:
-	srp_unmap_data(scmnd, target, cmd);
+	srp_unmap_data(scmnd, target, req);
 
 err:
 	return SCSI_MLQUEUE_HOST_BUSY;
--- linux-kernel/infiniband/ulp/srp/ib_srp.h	(revision 3613)
+++ linux-kernel/infiniband/ulp/srp/ib_srp.h	(working copy)
@@ -94,6 +94,7 @@ struct srp_request {
 	struct scsi_cmnd       *scmnd;
 	struct srp_iu	       *cmd;
 	struct srp_iu	       *tsk_mgmt;
+	DECLARE_PCI_UNMAP_ADDR(direct_mapping)
 	struct completion	done;
 	short			next;
 	u8			cmd_done;



More information about the general mailing list