mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-02-13 16:11:54 +00:00
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.de Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: David Disseldorp <ddiss@suse.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
5f306aff34
commit
b92fcfcb68
@ -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(
|
|||||||
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,30 +585,26 @@ 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;
|
||||||
|
out:
|
||||||
transport_generic_free_cmd(se_cmd, 0);
|
transport_generic_free_cmd(se_cmd, 0);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int target_xcopy_write_destination(
|
static int target_xcopy_write_destination(
|
||||||
struct se_cmd *ec_cmd,
|
struct se_cmd *ec_cmd,
|
||||||
struct xcopy_op *xop,
|
struct xcopy_op *xop,
|
||||||
@ -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,27 +630,23 @@ 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);
|
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;
|
||||||
|
out:
|
||||||
transport_generic_free_cmd(se_cmd, 0);
|
transport_generic_free_cmd(se_cmd, 0);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void target_xcopy_do_work(struct work_struct *work)
|
static void target_xcopy_do_work(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct xcopy_op *xop = container_of(work, struct xcopy_op, xop_work);
|
struct xcopy_op *xop = container_of(work, struct xcopy_op, xop_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)
|
|||||||
|
|
||||||
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 {
|
|||||||
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 {
|
|||||||
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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user