Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iser-target: Skip data copy if all the command data comes as immediate

Given that supporting zcopy immediate data for all IOs requires
iser driver to use its own buffer allocations, we settle with
avoiding data copy for IOs with data length of up to 8K (which
is more latency sensitive anyway).

This trims IO write latency by up to 3us and increase IOPs
by up to 40% by saving CPU time doing sg_copy_from_buffer
(8K IO size is the obvious winner here).

Signed-off-by: Jenny Derzhavetz <jennyf@mellanox.com>
Signed-off-by: Sagi Grimberg <sagig@mellanox.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>

authored by

Jenny Derzhavetz and committed by
Nicholas Bellinger
9fd60088 4366b19c

+19 -8
+18 -8
drivers/infiniband/ulp/isert/ib_isert.c
··· 1315 1315 { 1316 1316 struct iscsi_conn *conn = isert_conn->conn; 1317 1317 struct iscsi_scsi_req *hdr = (struct iscsi_scsi_req *)buf; 1318 - struct scatterlist *sg; 1319 1318 int imm_data, imm_data_len, unsol_data, sg_nents, rc; 1320 1319 bool dump_payload = false; 1320 + unsigned int data_len; 1321 1321 1322 1322 rc = iscsit_setup_scsi_cmd(conn, cmd, buf); 1323 1323 if (rc < 0) ··· 1326 1326 imm_data = cmd->immediate_data; 1327 1327 imm_data_len = cmd->first_burst_len; 1328 1328 unsol_data = cmd->unsolicited_data; 1329 + data_len = cmd->se_cmd.data_length; 1329 1330 1331 + if (imm_data && imm_data_len == data_len) 1332 + cmd->se_cmd.se_cmd_flags |= SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC; 1330 1333 rc = iscsit_process_scsi_cmd(conn, cmd, hdr); 1331 1334 if (rc < 0) { 1332 1335 return 0; ··· 1341 1338 if (!imm_data) 1342 1339 return 0; 1343 1340 1344 - sg = &cmd->se_cmd.t_data_sg[0]; 1345 - sg_nents = max(1UL, DIV_ROUND_UP(imm_data_len, PAGE_SIZE)); 1346 - 1347 - isert_dbg("Copying Immediate SG: %p sg_nents: %u from %p imm_data_len: %d\n", 1348 - sg, sg_nents, &rx_desc->data[0], imm_data_len); 1349 - 1350 - sg_copy_from_buffer(sg, sg_nents, &rx_desc->data[0], imm_data_len); 1341 + if (imm_data_len != data_len) { 1342 + sg_nents = max(1UL, DIV_ROUND_UP(imm_data_len, PAGE_SIZE)); 1343 + sg_copy_from_buffer(cmd->se_cmd.t_data_sg, sg_nents, 1344 + &rx_desc->data[0], imm_data_len); 1345 + isert_dbg("Copy Immediate sg_nents: %u imm_data_len: %d\n", 1346 + sg_nents, imm_data_len); 1347 + } else { 1348 + sg_init_table(&isert_cmd->sg, 1); 1349 + cmd->se_cmd.t_data_sg = &isert_cmd->sg; 1350 + cmd->se_cmd.t_data_nents = 1; 1351 + sg_set_buf(&isert_cmd->sg, &rx_desc->data[0], imm_data_len); 1352 + isert_dbg("Transfer Immediate imm_data_len: %d\n", 1353 + imm_data_len); 1354 + } 1351 1355 1352 1356 cmd->write_data_done += imm_data_len; 1353 1357
+1
drivers/infiniband/ulp/isert/ib_isert.h
··· 139 139 struct iser_rx_desc *rx_desc; 140 140 struct isert_rdma_wr rdma_wr; 141 141 struct work_struct comp_work; 142 + struct scatterlist sg; 142 143 }; 143 144 144 145 struct isert_device;