Uniform max queue depth handling in iSCSI

git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@1556 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2010-03-18 11:44:39 +00:00
parent 2fcee2a380
commit 1f216064f3
10 changed files with 80 additions and 37 deletions
+1
View 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;
+2 -2
View 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);
}
+9 -9
View 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);
+1 -1
View 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?
*/
+16 -9
View 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);
}
+5 -3
View 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:
+21 -12
View 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,
+7 -1
View File
@@ -30,6 +30,11 @@
#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);
+12
View 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)
+6
View 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;