Added limit on maximum queued on a device commands

git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@126 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2007-06-08 10:54:18 +00:00
parent fc854f8279
commit 54710618be
4 changed files with 39 additions and 13 deletions
+4 -1
View File
@@ -1184,6 +1184,9 @@ struct scst_device
/* Lists of commands with the lock, if dedicated threads are used */
struct scst_cmd_lists cmd_lists;
/* How many cmds alive on this dev */
atomic_t dev_cmd_count;
unsigned short type; /* SCSI type of the device */
/*************************************************************
@@ -1283,7 +1286,7 @@ struct scst_tgt_dev
lun_t lun; /* to save extra dereferences */
/* How many cmds alive on this dev in this session */
atomic_t cmd_count;
atomic_t tgt_dev_cmd_count;
int gfp_mask;
struct sgv_pool *pool;
+6 -3
View File
@@ -162,6 +162,7 @@ int scst_alloc_device(int gfp_mask, struct scst_device **out_dev)
}
dev->p_cmd_lists = &scst_main_cmd_lists;
atomic_set(&dev->dev_cmd_count, 0);
spin_lock_init(&dev->dev_lock);
atomic_set(&dev->on_dev_count, 0);
INIT_LIST_HEAD(&dev->blocked_cmd_list);
@@ -354,7 +355,7 @@ static struct scst_tgt_dev *scst_alloc_add_tgt_dev(struct scst_session *sess,
tgt_dev->lun = acg_dev->lun;
tgt_dev->acg_dev = acg_dev;
tgt_dev->sess = sess;
atomic_set(&tgt_dev->cmd_count, 0);
atomic_set(&tgt_dev->tgt_dev_cmd_count, 0);
tgt_dev->gfp_mask = __GFP_NOWARN;
tgt_dev->pool = &scst_sgv.norm;
@@ -1211,8 +1212,10 @@ void scst_free_cmd(struct scst_cmd *cmd)
}
#endif
if (likely(cmd->tgt_dev != NULL))
atomic_dec(&cmd->tgt_dev->cmd_count);
if (likely(cmd->tgt_dev != NULL)) {
atomic_dec(&cmd->tgt_dev->tgt_dev_cmd_count);
atomic_dec(&cmd->dev->dev_cmd_count);
}
/*
* cmd->mgmt_cmnd can't being changed here, since for that it either
+11 -4
View File
@@ -105,12 +105,19 @@ extern unsigned long scst_trace_flag;
/**
** Maximum count of uncompleted commands that an initiator could
** queue on any device. Then it will take TASK QUEUE FULL status.
** queue on any device. Then it will start getting TASK QUEUE FULL status.
**/
#define SCST_MAX_DEVICE_COMMANDS 128
#define SCST_MAX_TGT_DEV_COMMANDS 64
#define SCST_TGT_RETRY_TIMEOUT (3/2*HZ)
#define SCST_CMD_MEM_TIMEOUT (120*HZ)
/**
** Maximum count of uncompleted commands that could be queued on any device.
** Then initiators sending commands to this device will start getting
** TASK QUEUE FULL status.
**/
#define SCST_MAX_DEV_COMMANDS 256
#define SCST_TGT_RETRY_TIMEOUT (3/2*HZ)
#define SCST_CMD_MEM_TIMEOUT (120*HZ)
static inline int scst_get_context(void) {
if (in_irq())
+18 -5
View File
@@ -2632,15 +2632,23 @@ static int __scst_init_cmd(struct scst_cmd *cmd)
if (likely(res == 0)) {
int cnt;
cmd->state = SCST_CMD_STATE_DEV_PARSE;
cnt = atomic_inc_return(&cmd->tgt_dev->cmd_count);
if (unlikely(cnt > SCST_MAX_DEVICE_COMMANDS)) {
cnt = atomic_inc_return(&cmd->tgt_dev->tgt_dev_cmd_count);
if (unlikely(cnt > SCST_MAX_TGT_DEV_COMMANDS)) {
TRACE(TRACE_RETRY, "Too many pending commands in "
"session, returning BUSY to initiator \"%s\"",
(cmd->sess->initiator_name[0] == '\0') ?
"Anonymous" : cmd->sess->initiator_name);
scst_set_busy(cmd);
cmd->state = SCST_CMD_STATE_XMIT_RESP;
} else if (!cmd->no_sn)
goto out_busy;
}
cnt = atomic_inc_return(&cmd->dev->dev_cmd_count);
if (unlikely(cnt > SCST_MAX_DEV_COMMANDS)) {
TRACE(TRACE_RETRY, "Too many pending device commands, "
"returning BUSY to initiator \"%s\"",
(cmd->sess->initiator_name[0] == '\0') ?
"Anonymous" : cmd->sess->initiator_name);
goto out_busy;
}
if (!cmd->no_sn)
scst_cmd_set_sn(cmd);
} else if (res < 0) {
TRACE_DBG("Finishing cmd %p", cmd);
@@ -2653,6 +2661,11 @@ static int __scst_init_cmd(struct scst_cmd *cmd)
out:
TRACE_EXIT_RES(res);
return res;
out_busy:
scst_set_busy(cmd);
cmd->state = SCST_CMD_STATE_XMIT_RESP;
goto out;
}
/* Called under scst_init_lock and IRQs disabled */