Uniform max queue depth handling in iSCSI
authorvlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Thu, 18 Mar 2010 11:44:39 +0000 (11:44 +0000)
committervlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Thu, 18 Mar 2010 11:44:39 +0000 (11:44 +0000)
git-svn-id: https://scst.svn.sourceforge.net/svnroot/scst/trunk@1556 d57e44dd-8a1f-0410-8b47-8ef2f437770f

iscsi-scst/kernel/config.c
iscsi-scst/kernel/conn.c
iscsi-scst/kernel/iscsi.c
iscsi-scst/kernel/nthread.c
iscsi-scst/kernel/param.c
iscsi-scst/usr/ctldev.c
iscsi-scst/usr/iscsi_scstd.c
iscsi-scst/usr/iscsid.h
scst/include/scst.h
scst/src/scst_lib.c

index f48d8ea..09de558 100644 (file)
@@ -1004,6 +1004,7 @@ static int iscsi_register(void __user *arg)
 
        memset(&reg, 0, sizeof(reg));
        reg.max_data_seg_len = ISCSI_CONN_IOV_MAX << PAGE_SHIFT;
+       reg.max_queued_cmds = scst_get_max_lun_commands(NULL, NO_SUCH_LUN);
 
        res = 0;
 
index 9311a8b..4f063bc 100644 (file)
@@ -473,7 +473,7 @@ static void conn_nop_in_delayed_work_fn(struct delayed_work *work)
        }
 
        if (conn->nop_in_interval > 0) {
-               TRACE_DBG("Reschedule NOP-In work for conn %p", conn);
+               TRACE_DBG("Reschedule Nop-In work for conn %p", conn);
                schedule_delayed_work(&conn->nop_in_delayed_work,
                        conn->nop_in_interval + ISCSI_ADD_SCHED_TIME);
        }
@@ -755,7 +755,7 @@ static int iscsi_conn_alloc(struct iscsi_session *session,
        conn->rsp_timeout = session->tgt_params.rsp_timeout * HZ;
        conn->nop_in_interval = session->tgt_params.nop_in_interval * HZ;
        if (conn->nop_in_interval > 0) {
-               TRACE_DBG("Schedule NOP-In work for conn %p", conn);
+               TRACE_DBG("Schedule Nop-In work for conn %p", conn);
                schedule_delayed_work(&conn->nop_in_delayed_work,
                        conn->nop_in_interval + ISCSI_ADD_SCHED_TIME);
        }
index eaf06b6..90c3532 100644 (file)
@@ -1558,7 +1558,7 @@ static int nop_out_start(struct iscsi_cmnd *cmnd)
        iscsi_extracheck_is_rd_thread(conn);
 
        if (!(req_hdr->flags & ISCSI_FLG_FINAL)) {
-               PRINT_ERROR("%s", "Initiator sent NOP-Out with not a single "
+               PRINT_ERROR("%s", "Initiator sent Nop-Out with not a single "
                        "PDU");
                err = -ISCSI_REASON_PROTOCOL_ERROR;
                goto out;
@@ -1567,7 +1567,7 @@ static int nop_out_start(struct iscsi_cmnd *cmnd)
        if (cmnd_itt(cmnd) == cpu_to_be32(ISCSI_RESERVED_TAG)) {
                if (unlikely(!(cmnd->pdu.bhs.opcode & ISCSI_OP_IMMEDIATE)))
                        PRINT_ERROR("%s", "Initiator sent RESERVED tag for "
-                               "non-immediate NOP-Out command");
+                               "non-immediate Nop-Out command");
        }
 
        spin_lock(&conn->session->sn_lock);
@@ -1588,7 +1588,7 @@ static int nop_out_start(struct iscsi_cmnd *cmnd)
                                                &cmnd->sg_cnt);
                        if (sg == NULL) {
                                TRACE(TRACE_OUT_OF_MEM, "Allocating buffer for"
-                                     " %d NOP-Out payload failed", size);
+                                     " %d Nop-Out payload failed", size);
                                err = -ISCSI_REASON_OUT_OF_RESOURCES;
                                goto out;
                        }
@@ -2509,7 +2509,7 @@ static void nop_out_exec(struct iscsi_cmnd *req)
                struct iscsi_cmnd *r;
                struct iscsi_conn *conn = req->conn;
 
-               TRACE_DBG("Receive NOP-in response (ttt 0x%08x)",
+               TRACE_DBG("Receive Nop-In response (ttt 0x%08x)",
                        be32_to_cpu(cmnd_ttt(req)));
 
                spin_lock_bh(&conn->nop_req_list_lock);
@@ -2526,8 +2526,8 @@ static void nop_out_exec(struct iscsi_cmnd *req)
                if (found)
                        cmnd_put(r);
                else
-                       TRACE_MGMT_DBG("%s", "Got NOP-out response without "
-                               "corresponding NOP-in request");
+                       TRACE_MGMT_DBG("%s", "Got Nop-out response without "
+                               "corresponding Nop-In request");
        }
 
        req_cmnd_release(req);
@@ -3489,13 +3489,13 @@ void iscsi_send_nop_in(struct iscsi_conn *conn)
 
        req = cmnd_alloc(conn, NULL);
        if (req == NULL) {
-               PRINT_ERROR("%s", "Unable to alloc fake NOP-IN request");
+               PRINT_ERROR("%s", "Unable to alloc fake Nop-In request");
                goto out_err;
        }
 
        rsp = iscsi_alloc_main_rsp(req);
        if (rsp == NULL) {
-               PRINT_ERROR("%s", "Unable to alloc NOP-IN rsp");
+               PRINT_ERROR("%s", "Unable to alloc Nop-In rsp");
                goto out_err_free_req;
        }
 
@@ -3512,7 +3512,7 @@ void iscsi_send_nop_in(struct iscsi_conn *conn)
 
        /* Supposed that all other fields are zeroed */
 
-       TRACE_DBG("Sending NOP-in request (ttt 0x%08x)", rsp_hdr->ttt);
+       TRACE_DBG("Sending Nop-In request (ttt 0x%08x)", rsp_hdr->ttt);
        spin_lock_bh(&conn->nop_req_list_lock);
        list_add_tail(&rsp->nop_req_list_entry, &conn->nop_req_list);
        spin_unlock_bh(&conn->nop_req_list_lock);
index 5d619c8..623f418 100644 (file)
@@ -767,7 +767,7 @@ static int iscsi_rx_check_ddigest(struct iscsi_conn *conn)
                        cmnd_get(cmnd);
                } else if (cmnd_opcode(cmnd) != ISCSI_OP_SCSI_DATA_OUT) {
                        /*
-                        * We could get here only for NOP-Out. ISCSI RFC
+                        * We could get here only for Nop-Out. ISCSI RFC
                         * doesn't specify how to deal with digest errors in
                         * this case. Is closing connection correct?
                         */
index 9420f25..cc54efa 100644 (file)
@@ -22,12 +22,17 @@ do {                                                                                \
                TRACE_DBG("%s: %u", #word, (iparams)[key_##word]);              \
                if ((iparams)[key_##word] < (min) ||                            \
                        (iparams)[key_##word] > (max)) {                        \
-                       PRINT_ERROR("%s: %u is out of range (%u %u)",           \
-                               #word, (iparams)[key_##word], (min), (max));    \
-                       if ((iparams)[key_##word] < (min))                      \
+                       if ((iparams)[key_##word] < (min)) {                    \
                                (iparams)[key_##word] = (min);                  \
-                       else                                                    \
+                               PRINT_WARNING("%s: %u is too small, resetting " \
+                                       "it to allowed min %u",                 \
+                                       #word, (iparams)[key_##word], (min));   \
+                       } else {                                                \
+                               PRINT_WARNING("%s: %u is too big, resetting "   \
+                                       "it to allowed max %u",                 \
+                                       #word, (iparams)[key_##word], (max));   \
                                (iparams)[key_##word] = (max);                  \
+                       }                                                       \
                }                                                               \
        }                                                                       \
 } while (0)
@@ -186,12 +191,14 @@ static void sess_params_get(struct iscsi_sess_params *params,
 }
 
 /* target_mutex supposed to be locked */
-static void tgt_params_check(struct iscsi_kern_params_info *info)
+static void tgt_params_check(struct iscsi_session *session,
+       struct iscsi_kern_params_info *info)
 {
        int32_t *iparams = info->target_params;
 
        CHECK_PARAM(info, iparams, queued_cmnds, MIN_NR_QUEUED_CMNDS,
-                   MAX_NR_QUEUED_CMNDS);
+               min_t(int, MAX_NR_QUEUED_CMNDS,
+                     scst_get_max_lun_commands(session->scst_sess, NO_SUCH_LUN)));
        CHECK_PARAM(info, iparams, rsp_timeout, MIN_RSP_TIMEOUT,
                MAX_RSP_TIMEOUT);
        CHECK_PARAM(info, iparams, nop_in_interval, MIN_NOP_IN_INTERVAL,
@@ -209,14 +216,14 @@ static int iscsi_tgt_params_set(struct iscsi_session *session,
        if (set) {
                struct iscsi_conn *conn;
 
-               tgt_params_check(info);
+               tgt_params_check(session, info);
 
                SET_PARAM(params, info, iparams, queued_cmnds);
                SET_PARAM(params, info, iparams, rsp_timeout);
                SET_PARAM(params, info, iparams, nop_in_interval);
 
                PRINT_INFO("Target parameters set for session %llx: "
-                       "QueuedCommands %d, Response timeout %d, NOP-in "
+                       "QueuedCommands %d, Response timeout %d, Nop-In "
                        "interval %d", session->sid, params->queued_cmnds,
                        params->rsp_timeout, params->nop_in_interval);
 
@@ -226,7 +233,7 @@ static int iscsi_tgt_params_set(struct iscsi_session *session,
                        conn->nop_in_interval = session->tgt_params.nop_in_interval * HZ;
                        spin_lock_bh(&iscsi_rd_lock);
                        if (!conn->closing && (conn->nop_in_interval > 0)) {
-                               TRACE_DBG("Schedule NOP-In work for conn %p", conn);
+                               TRACE_DBG("Schedule Nop-In work for conn %p", conn);
                                schedule_delayed_work(&conn->nop_in_delayed_work,
                                        conn->nop_in_interval + ISCSI_ADD_SCHED_TIME);
                        }
index dd34f72..26e36c9 100644 (file)
@@ -29,7 +29,7 @@
 
 #define CTL_DEVICE     "/dev/iscsi-scst-ctl"
 
-int kernel_open(int *max_data_seg_len)
+int kernel_open(void)
 {
        FILE *f;
        char devname[256];
@@ -91,8 +91,10 @@ int kernel_open(int *max_data_seg_len)
                        "kernel module?\n", strerror(errno));
                goto out_close;
        } else {
-               log_debug(0, "MAX_DATA_SEG_LEN %d", err);
-               *max_data_seg_len = reg.max_data_seg_len;
+               log_debug(0, "max_data_seg_len %d, max_queued_cmds %d, ",
+                       reg.max_data_seg_len, reg.max_queued_cmds);
+               iscsi_init_params.max_data_seg_len = reg.max_data_seg_len;
+               iscsi_init_params.max_queued_cmds = reg.max_queued_cmds;
        }
 
 out:
index c7c27ab..e1ab45d 100644 (file)
@@ -62,6 +62,8 @@ static int incoming_cnt;
 int ctrl_fd, ipc_fd, nl_fd;
 int conn_blocked;
 
+struct iscsi_init_params iscsi_init_params;
+
 static char program_name[] = "iscsi-scstd";
 
 static struct option const long_options[] =
@@ -566,7 +568,7 @@ static void event_loop(void)
        }
 }
 
-static void init_max_data_seg_len(int max_data_seg_len)
+static void init_max_params(void)
 {
        if ((session_keys[key_max_recv_data_length].local_def != -1) ||
            (session_keys[key_max_recv_data_length].max != -1) ||
@@ -580,21 +582,29 @@ static void init_max_data_seg_len(int max_data_seg_len)
                exit(-1);
        }
 
+       /* QueuedCommands */
+       target_keys[key_queued_cmnds].local_def = min(target_keys[key_queued_cmnds].local_def,
+                                                     iscsi_init_params.max_queued_cmds);
+       target_keys[key_queued_cmnds].max = min(target_keys[key_queued_cmnds].max,
+                                               iscsi_init_params.max_queued_cmds);
+       target_keys[key_queued_cmnds].min = min(target_keys[key_queued_cmnds].min,
+                                               iscsi_init_params.max_queued_cmds);
+
        /* MaxRecvDataSegmentLength */
-       session_keys[key_max_recv_data_length].local_def = max_data_seg_len;
-       session_keys[key_max_recv_data_length].max = max_data_seg_len;
+       session_keys[key_max_recv_data_length].local_def = iscsi_init_params.max_data_seg_len;
+       session_keys[key_max_recv_data_length].max = iscsi_init_params.max_data_seg_len;
 
        /* MaxXmitDataSegmentLength */
-       session_keys[key_max_xmit_data_length].local_def = max_data_seg_len;
-       session_keys[key_max_xmit_data_length].max = max_data_seg_len;
+       session_keys[key_max_xmit_data_length].local_def = iscsi_init_params.max_data_seg_len;
+       session_keys[key_max_xmit_data_length].max = iscsi_init_params.max_data_seg_len;
 
        /* MaxBurstLength */
-       session_keys[key_max_burst_length].local_def = max_data_seg_len;
-       session_keys[key_max_burst_length].max = max_data_seg_len;
+       session_keys[key_max_burst_length].local_def = iscsi_init_params.max_data_seg_len;
+       session_keys[key_max_burst_length].max = iscsi_init_params.max_data_seg_len;
 
        /* FirstBurstLength */
-       session_keys[key_first_burst_length].local_def = max_data_seg_len;
-       session_keys[key_first_burst_length].max = max_data_seg_len;
+       session_keys[key_first_burst_length].local_def = iscsi_init_params.max_data_seg_len;
+       session_keys[key_first_burst_length].max = iscsi_init_params.max_data_seg_len;
 
        return;
 }
@@ -605,7 +615,6 @@ int main(int argc, char **argv)
        char *config = NULL;
        uid_t uid = 0;
        gid_t gid = 0;
-       int max_data_seg_len = -1;
        int err;
 
 #ifdef CONFIG_SCST_PROC
@@ -668,10 +677,10 @@ int main(int argc, char **argv)
                exit(-1);
        };
 
-       if ((ctrl_fd = kernel_open(&max_data_seg_len)) < 0)
+       if ((ctrl_fd = kernel_open()) < 0)
                exit(-1);
 
-       init_max_data_seg_len(max_data_seg_len);
+       init_max_params();
 
 #ifndef CONFIG_SCST_PROC
        err = kernel_attr_add(NULL, ISCSI_ISNS_SERVER_PARAM_NAME,
index 227400a..f0ef0d2 100644 (file)
 #define sBUG() assert(0)
 #define sBUG_ON(p) assert(!(p))
 
+struct iscsi_init_params {
+       int max_data_seg_len;
+       int max_queued_cmds;
+};
+
 struct buf_segment {
        struct __qelem entry;
 
@@ -199,6 +204,7 @@ extern void conn_free_rsp_buf_list(struct connection *conn);
 
 /* iscsi_scstd.c */
 extern uint16_t server_port;
+extern struct iscsi_init_params iscsi_init_params;
 extern void isns_set_fd(int isns, int scn_listen, int scn);
 
 /* iscsid.c */
@@ -253,7 +259,7 @@ extern int iscsi_adm_request_listen(void);
 extern int iscsi_adm_request_handle(int accept_fd);
 
 /* ctldev.c */
-extern int kernel_open(int *max_data_seg_len);
+extern int kernel_open(void);
 extern int kernel_params_get(u32 tid, u64 sid, int type, struct iscsi_param *params);
 extern int kernel_params_set(u32 tid, u64 sid, int type, u32 partial,
        const struct iscsi_param *params);
index 5c2bc74..7dc48ff 100644 (file)
@@ -3638,6 +3638,18 @@ int scst_tape_generic_dev_done(struct scst_cmd *cmd,
  */
 int scst_obtain_device_parameters(struct scst_device *dev);
 
+/*
+ * Returns maximum commands count which can be queued to this LUN in this
+ * session.
+ *
+ * If lun is NO_SUCH_LUN, returns minimum of maximum commands count which
+ * can be queued to any LUN in this session.
+ *
+ * If sess is NULL, returns minimum of maximum commands count which can be
+ * queued to any SCST device.
+ */
+int scst_get_max_lun_commands(struct scst_session *sess, uint64_t lun);
+
 /*
  * Has to be put here open coded, because Linux doesn't have equivalent, which
  * allows exclusive wake ups of threads in LIFO order. We need it to let (yet)
index 57c640b..ab99fd9 100644 (file)
@@ -5826,6 +5826,12 @@ out:
        return;
 }
 
+int scst_get_max_lun_commands(struct scst_session *sess, uint64_t lun)
+{
+       return SCST_MAX_TGT_DEV_COMMANDS;
+}
+EXPORT_SYMBOL(scst_get_max_lun_commands);
+
 char *scst_get_next_lexem(char **token_str)
 {
        char *p = *token_str;