Commit b92fcfcb authored by David Disseldorp's avatar David Disseldorp Committed by Martin K. Petersen

scsi: target: use the stack for XCOPY passthrough cmds

Reads and writes in the XCOPY loop are synchronous, so needn't be heap
allocated / freed with each loop.

Link: https://lore.kernel.org/r/20200327141954.955-6-ddiss@suse.deReviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarDavid Disseldorp <ddiss@suse.de>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 5f306aff
...@@ -410,7 +410,8 @@ static void xcopy_pt_release_cmd(struct se_cmd *se_cmd) ...@@ -410,7 +410,8 @@ static void xcopy_pt_release_cmd(struct se_cmd *se_cmd)
struct xcopy_pt_cmd *xpt_cmd = container_of(se_cmd, struct xcopy_pt_cmd *xpt_cmd = container_of(se_cmd,
struct xcopy_pt_cmd, se_cmd); struct xcopy_pt_cmd, se_cmd);
kfree(xpt_cmd); /* xpt_cmd is on the stack, nothing to free here */
pr_debug("xpt_cmd done: %p\n", xpt_cmd);
} }
static int xcopy_pt_check_stop_free(struct se_cmd *se_cmd) static int xcopy_pt_check_stop_free(struct se_cmd *se_cmd)
...@@ -566,20 +567,15 @@ static int target_xcopy_read_source( ...@@ -566,20 +567,15 @@ static int target_xcopy_read_source(
sector_t src_lba, sector_t src_lba,
u32 src_sectors) u32 src_sectors)
{ {
struct xcopy_pt_cmd *xpt_cmd; struct xcopy_pt_cmd xpt_cmd;
struct se_cmd *se_cmd; struct se_cmd *se_cmd = &xpt_cmd.se_cmd;
u32 length = (src_sectors * src_dev->dev_attrib.block_size); u32 length = (src_sectors * src_dev->dev_attrib.block_size);
int rc; int rc;
unsigned char cdb[16]; unsigned char cdb[16];
bool remote_port = (xop->op_origin == XCOL_DEST_RECV_OP); bool remote_port = (xop->op_origin == XCOL_DEST_RECV_OP);
xpt_cmd = kzalloc(sizeof(struct xcopy_pt_cmd), GFP_KERNEL); memset(&xpt_cmd, 0, sizeof(xpt_cmd));
if (!xpt_cmd) { init_completion(&xpt_cmd.xpt_passthrough_sem);
pr_err("Unable to allocate xcopy_pt_cmd\n");
return -ENOMEM;
}
init_completion(&xpt_cmd->xpt_passthrough_sem);
se_cmd = &xpt_cmd->se_cmd;
memset(&cdb[0], 0, 16); memset(&cdb[0], 0, 16);
cdb[0] = READ_16; cdb[0] = READ_16;
...@@ -589,28 +585,24 @@ static int target_xcopy_read_source( ...@@ -589,28 +585,24 @@ static int target_xcopy_read_source(
(unsigned long long)src_lba, src_sectors, length); (unsigned long long)src_lba, src_sectors, length);
transport_init_se_cmd(se_cmd, &xcopy_pt_tfo, &xcopy_pt_sess, length, transport_init_se_cmd(se_cmd, &xcopy_pt_tfo, &xcopy_pt_sess, length,
DMA_FROM_DEVICE, 0, &xpt_cmd->sense_buffer[0]); DMA_FROM_DEVICE, 0, &xpt_cmd.sense_buffer[0]);
xop->src_pt_cmd = xpt_cmd;
rc = target_xcopy_setup_pt_cmd(xpt_cmd, xop, src_dev, &cdb[0], rc = target_xcopy_setup_pt_cmd(&xpt_cmd, xop, src_dev, &cdb[0],
remote_port); remote_port);
if (rc < 0) { if (rc < 0) {
ec_cmd->scsi_status = xpt_cmd->se_cmd.scsi_status; ec_cmd->scsi_status = se_cmd->scsi_status;
transport_generic_free_cmd(se_cmd, 0); goto out;
return rc;
} }
pr_debug("XCOPY-READ: Saved xop->xop_data_sg: %p, num: %u for READ" pr_debug("XCOPY-READ: Saved xop->xop_data_sg: %p, num: %u for READ"
" memory\n", xop->xop_data_sg, xop->xop_data_nents); " memory\n", xop->xop_data_sg, xop->xop_data_nents);
rc = target_xcopy_issue_pt_cmd(xpt_cmd); rc = target_xcopy_issue_pt_cmd(&xpt_cmd);
if (rc < 0) { if (rc < 0)
ec_cmd->scsi_status = xpt_cmd->se_cmd.scsi_status; ec_cmd->scsi_status = se_cmd->scsi_status;
transport_generic_free_cmd(se_cmd, 0); out:
return rc; transport_generic_free_cmd(se_cmd, 0);
} return rc;
return 0;
} }
static int target_xcopy_write_destination( static int target_xcopy_write_destination(
...@@ -620,20 +612,15 @@ static int target_xcopy_write_destination( ...@@ -620,20 +612,15 @@ static int target_xcopy_write_destination(
sector_t dst_lba, sector_t dst_lba,
u32 dst_sectors) u32 dst_sectors)
{ {
struct xcopy_pt_cmd *xpt_cmd; struct xcopy_pt_cmd xpt_cmd;
struct se_cmd *se_cmd; struct se_cmd *se_cmd = &xpt_cmd.se_cmd;
u32 length = (dst_sectors * dst_dev->dev_attrib.block_size); u32 length = (dst_sectors * dst_dev->dev_attrib.block_size);
int rc; int rc;
unsigned char cdb[16]; unsigned char cdb[16];
bool remote_port = (xop->op_origin == XCOL_SOURCE_RECV_OP); bool remote_port = (xop->op_origin == XCOL_SOURCE_RECV_OP);
xpt_cmd = kzalloc(sizeof(struct xcopy_pt_cmd), GFP_KERNEL); memset(&xpt_cmd, 0, sizeof(xpt_cmd));
if (!xpt_cmd) { init_completion(&xpt_cmd.xpt_passthrough_sem);
pr_err("Unable to allocate xcopy_pt_cmd\n");
return -ENOMEM;
}
init_completion(&xpt_cmd->xpt_passthrough_sem);
se_cmd = &xpt_cmd->se_cmd;
memset(&cdb[0], 0, 16); memset(&cdb[0], 0, 16);
cdb[0] = WRITE_16; cdb[0] = WRITE_16;
...@@ -643,25 +630,21 @@ static int target_xcopy_write_destination( ...@@ -643,25 +630,21 @@ static int target_xcopy_write_destination(
(unsigned long long)dst_lba, dst_sectors, length); (unsigned long long)dst_lba, dst_sectors, length);
transport_init_se_cmd(se_cmd, &xcopy_pt_tfo, &xcopy_pt_sess, length, transport_init_se_cmd(se_cmd, &xcopy_pt_tfo, &xcopy_pt_sess, length,
DMA_TO_DEVICE, 0, &xpt_cmd->sense_buffer[0]); DMA_TO_DEVICE, 0, &xpt_cmd.sense_buffer[0]);
xop->dst_pt_cmd = xpt_cmd;
rc = target_xcopy_setup_pt_cmd(xpt_cmd, xop, dst_dev, &cdb[0], rc = target_xcopy_setup_pt_cmd(&xpt_cmd, xop, dst_dev, &cdb[0],
remote_port); remote_port);
if (rc < 0) { if (rc < 0) {
ec_cmd->scsi_status = xpt_cmd->se_cmd.scsi_status; ec_cmd->scsi_status = se_cmd->scsi_status;
transport_generic_free_cmd(se_cmd, 0); goto out;
return rc;
}
rc = target_xcopy_issue_pt_cmd(xpt_cmd);
if (rc < 0) {
ec_cmd->scsi_status = xpt_cmd->se_cmd.scsi_status;
transport_generic_free_cmd(se_cmd, 0);
return rc;
} }
return 0; rc = target_xcopy_issue_pt_cmd(&xpt_cmd);
if (rc < 0)
ec_cmd->scsi_status = se_cmd->scsi_status;
out:
transport_generic_free_cmd(se_cmd, 0);
return rc;
} }
static void target_xcopy_do_work(struct work_struct *work) static void target_xcopy_do_work(struct work_struct *work)
...@@ -736,10 +719,8 @@ static void target_xcopy_do_work(struct work_struct *work) ...@@ -736,10 +719,8 @@ static void target_xcopy_do_work(struct work_struct *work)
rc = target_xcopy_write_destination(ec_cmd, xop, dst_dev, rc = target_xcopy_write_destination(ec_cmd, xop, dst_dev,
dst_lba, cur_nolb); dst_lba, cur_nolb);
if (rc < 0) { if (rc < 0)
transport_generic_free_cmd(&xop->src_pt_cmd->se_cmd, 0);
goto out; goto out;
}
dst_lba += cur_nolb; dst_lba += cur_nolb;
pr_debug("target_xcopy_do_work: Incremented WRITE dst_lba to %llu\n", pr_debug("target_xcopy_do_work: Incremented WRITE dst_lba to %llu\n",
...@@ -747,9 +728,6 @@ static void target_xcopy_do_work(struct work_struct *work) ...@@ -747,9 +728,6 @@ static void target_xcopy_do_work(struct work_struct *work)
copied_nolb += cur_nolb; copied_nolb += cur_nolb;
nolb -= cur_nolb; nolb -= cur_nolb;
transport_generic_free_cmd(&xop->src_pt_cmd->se_cmd, 0);
transport_generic_free_cmd(&xop->dst_pt_cmd->se_cmd, 0);
} }
xcopy_pt_undepend_remotedev(xop); xcopy_pt_undepend_remotedev(xop);
......
...@@ -18,8 +18,6 @@ enum xcopy_origin_list { ...@@ -18,8 +18,6 @@ enum xcopy_origin_list {
XCOL_DEST_RECV_OP = 0x02, XCOL_DEST_RECV_OP = 0x02,
}; };
struct xcopy_pt_cmd;
struct xcopy_op { struct xcopy_op {
int op_origin; int op_origin;
...@@ -36,9 +34,6 @@ struct xcopy_op { ...@@ -36,9 +34,6 @@ struct xcopy_op {
unsigned short dtdi; unsigned short dtdi;
unsigned short nolb; unsigned short nolb;
struct xcopy_pt_cmd *src_pt_cmd;
struct xcopy_pt_cmd *dst_pt_cmd;
u32 xop_data_bytes; u32 xop_data_bytes;
u32 xop_data_nents; u32 xop_data_nents;
struct scatterlist *xop_data_sg; struct scatterlist *xop_data_sg;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment