diff mbox series

[RFC,5/5] scsi: target: avoid XCOPY per-loop read/write cmd allocations

Message ID 20200323165410.24423-6-ddiss@suse.de (mailing list archive)
State New, archived
Headers show
Series scsi: target: XCOPY performance | expand

Commit Message

David Disseldorp March 23, 2020, 4:54 p.m. UTC
Reads and writes in the XCOPY loop are synchronous, so needn't be
allocated / freed with each loop.

Signed-off-by: David Disseldorp <ddiss@suse.de>
---
 drivers/target/target_core_xcopy.c | 33 +++++++++------------------------
 drivers/target/target_core_xcopy.h | 10 +++++++---
 2 files changed, 16 insertions(+), 27 deletions(-)

Comments

Christoph Hellwig March 24, 2020, 9:23 a.m. UTC | #1
On Mon, Mar 23, 2020 at 05:54:10PM +0100, David Disseldorp wrote:
> Reads and writes in the XCOPY loop are synchronous, so needn't be
> allocated / freed with each loop.

That is true, but I think with your previous cleanups we can easily
go one step further and just allocate a single command and sense buffer
directly in struct xcopy_op, and just have local completions on the
stack.
David Disseldorp March 26, 2020, 9:20 p.m. UTC | #2
Hi Christoph,

Thanks for the feedback...

On Tue, 24 Mar 2020 02:23:23 -0700, Christoph Hellwig wrote:

> On Mon, Mar 23, 2020 at 05:54:10PM +0100, David Disseldorp wrote:
> > Reads and writes in the XCOPY loop are synchronous, so needn't be
> > allocated / freed with each loop.  
> 
> That is true, but I think with your previous cleanups we can easily
> go one step further and just allocate a single command and sense buffer
> directly in struct xcopy_op, and just have local completions on the
> stack.

I'm probably missing something, but having the (stack) completion
separate to the se_cmd and sense buffer would mean that it's no longer a
straightforward container_of() in the .check_stop_free() callback.

I've reworked this patch to put the entire xcopy_pt_cmd on the stack and
will send it out with v2.

Cheers, David
diff mbox series

Patch

diff --git a/drivers/target/target_core_xcopy.c b/drivers/target/target_core_xcopy.c
index e9c50766d4fc..cdc6c65168da 100644
--- a/drivers/target/target_core_xcopy.c
+++ b/drivers/target/target_core_xcopy.c
@@ -374,12 +374,6 @@  static int target_xcopy_parse_segment_descriptors(struct se_cmd *se_cmd,
  * Start xcopy_pt ops
  */
 
-struct xcopy_pt_cmd {
-	struct se_cmd se_cmd;
-	struct completion xpt_passthrough_sem;
-	unsigned char sense_buffer[TRANSPORT_SENSE_BUFFER];
-};
-
 struct se_portal_group xcopy_pt_tpg;
 static struct se_session xcopy_pt_sess;
 static struct se_node_acl xcopy_pt_nacl;
@@ -410,7 +404,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, se_cmd);
 
-	kfree(xpt_cmd);
+	/* xpt_cmd is backed by parent xop, nothing to free */
+	pr_debug("xpt_cmd done: %p\n", xpt_cmd);
 }
 
 static int xcopy_pt_check_stop_free(struct se_cmd *se_cmd)
@@ -582,18 +577,14 @@  static int target_xcopy_read_source(
 	sector_t src_lba,
 	u32 src_sectors)
 {
-	struct xcopy_pt_cmd *xpt_cmd;
+	struct xcopy_pt_cmd *xpt_cmd = &xop->src_pt_cmd;
 	struct se_cmd *se_cmd;
 	u32 length = (src_sectors * src_dev->dev_attrib.block_size);
 	int rc;
 	unsigned char cdb[16];
 	bool remote_port = (xop->op_origin == XCOL_DEST_RECV_OP);
 
-	xpt_cmd = kzalloc(sizeof(struct xcopy_pt_cmd), GFP_KERNEL);
-	if (!xpt_cmd) {
-		pr_err("Unable to allocate xcopy_pt_cmd\n");
-		return -ENOMEM;
-	}
+	memset(xpt_cmd, 0, sizeof(*xpt_cmd));
 	init_completion(&xpt_cmd->xpt_passthrough_sem);
 	se_cmd = &xpt_cmd->se_cmd;
 
@@ -606,7 +597,6 @@  static int target_xcopy_read_source(
 
 	transport_init_se_cmd(se_cmd, &xcopy_pt_tfo, &xcopy_pt_sess, length,
 			      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],
 				remote_port);
@@ -636,18 +626,14 @@  static int target_xcopy_write_destination(
 	sector_t dst_lba,
 	u32 dst_sectors)
 {
-	struct xcopy_pt_cmd *xpt_cmd;
+	struct xcopy_pt_cmd *xpt_cmd = &xop->dst_pt_cmd;
 	struct se_cmd *se_cmd;
 	u32 length = (dst_sectors * dst_dev->dev_attrib.block_size);
 	int rc;
 	unsigned char cdb[16];
 	bool remote_port = (xop->op_origin == XCOL_SOURCE_RECV_OP);
 
-	xpt_cmd = kzalloc(sizeof(struct xcopy_pt_cmd), GFP_KERNEL);
-	if (!xpt_cmd) {
-		pr_err("Unable to allocate xcopy_pt_cmd\n");
-		return -ENOMEM;
-	}
+	memset(xpt_cmd, 0, sizeof(*xpt_cmd));
 	init_completion(&xpt_cmd->xpt_passthrough_sem);
 	se_cmd = &xpt_cmd->se_cmd;
 
@@ -660,7 +646,6 @@  static int target_xcopy_write_destination(
 
 	transport_init_se_cmd(se_cmd, &xcopy_pt_tfo, &xcopy_pt_sess, length,
 			      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],
 				remote_port);
@@ -754,7 +739,7 @@  static void target_xcopy_do_work(struct work_struct *work)
 		rc = target_xcopy_write_destination(ec_cmd, xop, dst_dev,
 						dst_lba, cur_nolb);
 		if (rc < 0) {
-			transport_generic_free_cmd(&xop->src_pt_cmd->se_cmd, 0);
+			transport_generic_free_cmd(&xop->src_pt_cmd.se_cmd, 0);
 			goto out;
 		}
 
@@ -765,8 +750,8 @@  static void target_xcopy_do_work(struct work_struct *work)
 		copied_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);
+		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);
diff --git a/drivers/target/target_core_xcopy.h b/drivers/target/target_core_xcopy.h
index f1aaf7140798..f52640fcb12d 100644
--- a/drivers/target/target_core_xcopy.h
+++ b/drivers/target/target_core_xcopy.h
@@ -18,7 +18,11 @@  enum xcopy_origin_list {
 	XCOL_DEST_RECV_OP = 0x02,
 };
 
-struct xcopy_pt_cmd;
+struct xcopy_pt_cmd {
+	struct se_cmd se_cmd;
+	struct completion xpt_passthrough_sem;
+	unsigned char sense_buffer[TRANSPORT_SENSE_BUFFER];
+};
 
 struct xcopy_op {
 	int op_origin;
@@ -36,8 +40,8 @@  struct xcopy_op {
 	unsigned short dtdi;
 	unsigned short nolb;
 
-	struct xcopy_pt_cmd *src_pt_cmd;
-	struct xcopy_pt_cmd *dst_pt_cmd;
+	struct xcopy_pt_cmd src_pt_cmd;
+	struct xcopy_pt_cmd dst_pt_cmd;
 
 	u32 xop_data_bytes;
 	u32 xop_data_nents;