Skip to content

Commit df749cd

Browse files
Sagi Grimbergdledford
authored andcommitted
IB/iser: Support up to 8MB data transfer in a single command
iser support up to 512KB data transfer in a single scsi command. This means that larger IOs will split to different request. While iser can easily saturate FDR/EDR wires, some arrays are fine tuned for 1MB (or larger) IO sizes, hence add an option to support larger transfers (up to 8MB) if the device allows it. Given that a few target implementations don't support data transfers of more than 512KB by default and the fact that larger IO sizes require more resources, we introduce a module parameter to determine the maximum number of 512B sectors in a single scsi command. Users that are interested in larger transfers can change this value given that the target supports larger transfers. At the moment, iser works in 4K pages granularity, In a later stage we will get it to work with system page size instead. IO operations that consists of N pages will need a page vector of size N+1 in case the first SG element contains an offset. Given that some devices allocates memory regions in powers of 2, this means that allocating a region with N+1 pages, will result in region resources allocation of the next power of 2. Since we don't want that to happen, in case we are in the limit of IO size supported and the first SG element has an offset, we align the SG list using a bounce buffer (which is OK given that this is not likely to happen a lot). Signed-off-by: Sagi Grimberg <[email protected]> Signed-off-by: Doug Ledford <[email protected]>
1 parent f8db651 commit df749cd

File tree

5 files changed

+60
-7
lines changed

5 files changed

+60
-7
lines changed

drivers/infiniband/ulp/iser/iscsi_iser.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ static unsigned int iscsi_max_lun = 512;
9393
module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO);
9494
MODULE_PARM_DESC(max_lun, "Max LUNs to allow per session (default:512");
9595

96+
unsigned int iser_max_sectors = ISER_DEF_MAX_SECTORS;
97+
module_param_named(max_sectors, iser_max_sectors, uint, S_IRUGO | S_IWUSR);
98+
MODULE_PARM_DESC(max_sectors, "Max number of sectors in a single scsi command (default:1024");
99+
96100
bool iser_pi_enable = false;
97101
module_param_named(pi_enable, iser_pi_enable, bool, S_IRUGO);
98102
MODULE_PARM_DESC(pi_enable, "Enable T10-PI offload support (default:disabled)");
@@ -625,6 +629,8 @@ iscsi_iser_session_create(struct iscsi_endpoint *ep,
625629
if (ep) {
626630
iser_conn = ep->dd_data;
627631
max_cmds = iser_conn->max_cmds;
632+
shost->sg_tablesize = iser_conn->scsi_sg_tablesize;
633+
shost->max_sectors = iser_conn->scsi_max_sectors;
628634

629635
mutex_lock(&iser_conn->state_mutex);
630636
if (iser_conn->state != ISER_CONN_UP) {
@@ -966,8 +972,8 @@ static struct scsi_host_template iscsi_iser_sht = {
966972
.name = "iSCSI Initiator over iSER",
967973
.queuecommand = iscsi_queuecommand,
968974
.change_queue_depth = scsi_change_queue_depth,
969-
.sg_tablesize = ISCSI_ISER_SG_TABLESIZE,
970-
.max_sectors = 1024,
975+
.sg_tablesize = ISCSI_ISER_DEF_SG_TABLESIZE,
976+
.max_sectors = ISER_DEF_MAX_SECTORS,
971977
.cmd_per_lun = ISER_DEF_CMD_PER_LUN,
972978
.eh_abort_handler = iscsi_eh_abort,
973979
.eh_device_reset_handler= iscsi_eh_device_reset,

drivers/infiniband/ulp/iser/iscsi_iser.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,13 @@
9898
#define SHIFT_4K 12
9999
#define SIZE_4K (1ULL << SHIFT_4K)
100100
#define MASK_4K (~(SIZE_4K-1))
101-
/* support up to 512KB in one RDMA */
102-
#define ISCSI_ISER_SG_TABLESIZE (0x80000 >> SHIFT_4K)
101+
102+
/* Default support is 512KB I/O size */
103+
#define ISER_DEF_MAX_SECTORS 1024
104+
#define ISCSI_ISER_DEF_SG_TABLESIZE ((ISER_DEF_MAX_SECTORS * 512) >> SHIFT_4K)
105+
/* Maximum support is 8MB I/O size */
106+
#define ISCSI_ISER_MAX_SG_TABLESIZE ((16384 * 512) >> SHIFT_4K)
107+
103108
#define ISER_DEF_XMIT_CMDS_DEFAULT 512
104109
#if ISCSI_DEF_XMIT_CMDS_MAX > ISER_DEF_XMIT_CMDS_DEFAULT
105110
#define ISER_DEF_XMIT_CMDS_MAX ISCSI_DEF_XMIT_CMDS_MAX
@@ -504,6 +509,8 @@ struct ib_conn {
504509
* @rx_desc_head: head of rx_descs cyclic buffer
505510
* @rx_descs: rx buffers array (cyclic buffer)
506511
* @num_rx_descs: number of rx descriptors
512+
* @scsi_sg_tablesize: scsi host sg_tablesize
513+
* @scsi_max_sectors: scsi host max sectors
507514
*/
508515
struct iser_conn {
509516
struct ib_conn ib_conn;
@@ -528,6 +535,8 @@ struct iser_conn {
528535
unsigned int rx_desc_head;
529536
struct iser_rx_desc *rx_descs;
530537
u32 num_rx_descs;
538+
unsigned short scsi_sg_tablesize;
539+
unsigned int scsi_max_sectors;
531540
};
532541

533542
/**
@@ -583,6 +592,7 @@ extern struct iser_global ig;
583592
extern int iser_debug_level;
584593
extern bool iser_pi_enable;
585594
extern int iser_pi_guard;
595+
extern unsigned int iser_max_sectors;
586596

587597
int iser_assign_reg_ops(struct iser_device *device);
588598

drivers/infiniband/ulp/iser/iser_initiator.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ int iser_alloc_rx_descriptors(struct iser_conn *iser_conn,
259259
iser_conn->min_posted_rx = iser_conn->qp_max_recv_dtos >> 2;
260260

261261
if (device->reg_ops->alloc_reg_res(ib_conn, session->scsi_cmds_max,
262-
ISCSI_ISER_SG_TABLESIZE + 1))
262+
iser_conn->scsi_sg_tablesize))
263263
goto create_rdma_reg_res_failed;
264264

265265
if (iser_alloc_login_buf(iser_conn))

drivers/infiniband/ulp/iser/iser_memory.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,8 @@ static int iser_sg_to_page_vec(struct iser_data_buf *data,
363363
* consecutive SG elements are actually fragments of the same physcial page.
364364
*/
365365
static int iser_data_buf_aligned_len(struct iser_data_buf *data,
366-
struct ib_device *ibdev)
366+
struct ib_device *ibdev,
367+
unsigned sg_tablesize)
367368
{
368369
struct scatterlist *sg, *sgl, *next_sg = NULL;
369370
u64 start_addr, end_addr;
@@ -375,6 +376,14 @@ static int iser_data_buf_aligned_len(struct iser_data_buf *data,
375376
sgl = data->sg;
376377
start_addr = ib_sg_dma_address(ibdev, sgl);
377378

379+
if (unlikely(sgl[0].offset &&
380+
data->data_len >= sg_tablesize * PAGE_SIZE)) {
381+
iser_dbg("can't register length %lx with offset %x "
382+
"fall to bounce buffer\n", data->data_len,
383+
sgl[0].offset);
384+
return 0;
385+
}
386+
378387
for_each_sg(sgl, sg, data->dma_nents, i) {
379388
if (start_check && !IS_4K_ALIGNED(start_addr))
380389
break;
@@ -790,7 +799,8 @@ iser_handle_unaligned_buf(struct iscsi_iser_task *task,
790799
struct iser_device *device = iser_conn->ib_conn.device;
791800
int err, aligned_len;
792801

793-
aligned_len = iser_data_buf_aligned_len(mem, device->ib_device);
802+
aligned_len = iser_data_buf_aligned_len(mem, device->ib_device,
803+
iser_conn->scsi_sg_tablesize);
794804
if (aligned_len != mem->dma_nents) {
795805
err = fall_to_bounce_buf(task, mem, dir);
796806
if (err)

drivers/infiniband/ulp/iser/iser_verbs.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,31 @@ static void iser_connect_error(struct rdma_cm_id *cma_id)
756756
iser_conn->state = ISER_CONN_TERMINATING;
757757
}
758758

759+
static void
760+
iser_calc_scsi_params(struct iser_conn *iser_conn,
761+
unsigned int max_sectors)
762+
{
763+
struct iser_device *device = iser_conn->ib_conn.device;
764+
unsigned short sg_tablesize, sup_sg_tablesize;
765+
766+
sg_tablesize = DIV_ROUND_UP(max_sectors * 512, SIZE_4K);
767+
sup_sg_tablesize = min_t(unsigned, ISCSI_ISER_MAX_SG_TABLESIZE,
768+
device->dev_attr.max_fast_reg_page_list_len);
769+
770+
if (sg_tablesize > sup_sg_tablesize) {
771+
sg_tablesize = sup_sg_tablesize;
772+
iser_conn->scsi_max_sectors = sg_tablesize * SIZE_4K / 512;
773+
} else {
774+
iser_conn->scsi_max_sectors = max_sectors;
775+
}
776+
777+
iser_conn->scsi_sg_tablesize = sg_tablesize;
778+
779+
iser_dbg("iser_conn %p, sg_tablesize %u, max_sectors %u\n",
780+
iser_conn, iser_conn->scsi_sg_tablesize,
781+
iser_conn->scsi_max_sectors);
782+
}
783+
759784
/**
760785
* Called with state mutex held
761786
**/
@@ -794,6 +819,8 @@ static void iser_addr_handler(struct rdma_cm_id *cma_id)
794819
}
795820
}
796821

822+
iser_calc_scsi_params(iser_conn, iser_max_sectors);
823+
797824
ret = rdma_resolve_route(cma_id, 1000);
798825
if (ret) {
799826
iser_err("resolve route failed: %d\n", ret);

0 commit comments

Comments
 (0)