From 1548271ece9e9312fd5feb41fd58773b56a71d39 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 30 May 2007 12:57:19 -0500 Subject: [SCSI] libiscsi: make can_queue configurable This patch allows us to set can_queue and cmds_per_lun from userspace when we create the session/host. From there we can set it on a per target basis. The patch fully converts iscsi_tcp, but only hooks up ib_iser for cmd_per_lun since it currently has a lots of preallocations based on can_queue. Signed-off-by: Mike Christie Cc: Roland Dreier Signed-off-by: James Bottomley --- drivers/scsi/iscsi_tcp.c | 5 +++-- drivers/scsi/libiscsi.c | 28 +++++++++++++++++++++++++++- drivers/scsi/scsi_transport_iscsi.c | 2 ++ 3 files changed, 32 insertions(+), 3 deletions(-) (limited to 'drivers/scsi') diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 8edcfddc0baf..eca4d611dd49 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -2114,6 +2114,7 @@ iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats) static struct iscsi_cls_session * iscsi_tcp_session_create(struct iscsi_transport *iscsit, struct scsi_transport_template *scsit, + uint16_t cmds_max, uint16_t qdepth, uint32_t initial_cmdsn, uint32_t *hostno) { struct iscsi_cls_session *cls_session; @@ -2121,7 +2122,7 @@ iscsi_tcp_session_create(struct iscsi_transport *iscsit, uint32_t hn; int cmd_i; - cls_session = iscsi_session_setup(iscsit, scsit, + cls_session = iscsi_session_setup(iscsit, scsit, cmds_max, qdepth, sizeof(struct iscsi_tcp_cmd_task), sizeof(struct iscsi_tcp_mgmt_task), initial_cmdsn, &hn); @@ -2164,7 +2165,7 @@ static struct scsi_host_template iscsi_sht = { .name = "iSCSI Initiator over TCP/IP", .queuecommand = iscsi_queuecommand, .change_queue_depth = iscsi_change_queue_depth, - .can_queue = ISCSI_XMIT_CMDS_MAX - 1, + .can_queue = ISCSI_DEF_XMIT_CMDS_MAX - 1, .sg_tablesize = ISCSI_SG_TABLESIZE, .max_sectors = 0xFFFF, .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN, diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 938f527cd81a..1632866f52cc 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -1330,6 +1330,10 @@ EXPORT_SYMBOL_GPL(iscsi_pool_free); * iscsi_session_setup - create iscsi cls session and host and session * @scsit: scsi transport template * @iscsit: iscsi transport template + * @cmds_max: scsi host can queue + * @qdepth: scsi host cmds per lun + * @cmd_task_size: LLD ctask private data size + * @mgmt_task_size: LLD mtask private data size * @initial_cmdsn: initial CmdSN * @hostno: host no allocated * @@ -1339,6 +1343,7 @@ EXPORT_SYMBOL_GPL(iscsi_pool_free); struct iscsi_cls_session * iscsi_session_setup(struct iscsi_transport *iscsit, struct scsi_transport_template *scsit, + uint16_t cmds_max, uint16_t qdepth, int cmd_task_size, int mgmt_task_size, uint32_t initial_cmdsn, uint32_t *hostno) { @@ -1347,11 +1352,32 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct iscsi_cls_session *cls_session; int cmd_i; + if (qdepth > ISCSI_MAX_CMD_PER_LUN || qdepth < 1) { + if (qdepth != 0) + printk(KERN_ERR "iscsi: invalid queue depth of %d. " + "Queue depth must be between 1 and %d.\n", + qdepth, ISCSI_MAX_CMD_PER_LUN); + qdepth = ISCSI_DEF_CMD_PER_LUN; + } + + if (cmds_max < 2 || (cmds_max & (cmds_max - 1)) || + cmds_max >= ISCSI_MGMT_ITT_OFFSET) { + if (cmds_max != 0) + printk(KERN_ERR "iscsi: invalid can_queue of %d. " + "can_queue must be a power of 2 and between " + "2 and %d - setting to %d.\n", cmds_max, + ISCSI_MGMT_ITT_OFFSET, ISCSI_DEF_XMIT_CMDS_MAX); + cmds_max = ISCSI_DEF_XMIT_CMDS_MAX; + } + shost = scsi_host_alloc(iscsit->host_template, hostdata_privsize(sizeof(*session))); if (!shost) return NULL; + /* the iscsi layer takes one task for reserve */ + shost->can_queue = cmds_max - 1; + shost->cmd_per_lun = qdepth; shost->max_id = 1; shost->max_channel = 0; shost->max_lun = iscsit->max_lun; @@ -1365,7 +1391,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit, session->host = shost; session->state = ISCSI_STATE_FREE; session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX; - session->cmds_max = ISCSI_XMIT_CMDS_MAX; + session->cmds_max = cmds_max; session->cmdsn = initial_cmdsn; session->exp_cmdsn = initial_cmdsn + 1; session->max_cmdsn = initial_cmdsn + 1; diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 341d4fb5c6f8..859bd2100856 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -814,6 +814,8 @@ iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev) uint32_t hostno; session = transport->create_session(transport, &priv->t, + ev->u.c_session.cmds_max, + ev->u.c_session.queue_depth, ev->u.c_session.initial_cmdsn, &hostno); if (!session) -- cgit v1.2.3