[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