mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-18 03:01:26 +00:00
We need to abort internal commands as well.
git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@4470 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -4473,6 +4473,7 @@ static struct scst_cmd *scst_create_prepare_internal_cmd(
|
||||
struct scst_cmd *res;
|
||||
int rc;
|
||||
gfp_t gfp_mask = scst_cmd_atomic(orig_cmd) ? GFP_ATOMIC : GFP_KERNEL;
|
||||
unsigned long flags;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
@@ -4494,6 +4495,17 @@ static struct scst_cmd *scst_create_prepare_internal_cmd(
|
||||
res->queue_type = queue_type;
|
||||
res->data_direction = SCST_DATA_UNKNOWN;
|
||||
|
||||
/*
|
||||
* We need to keep it here to be able to abort during TM processing.
|
||||
* They should be aborted to (1) speed up TM processing and (2) to
|
||||
* guarantee that after a TM command finished the affected device(s)
|
||||
* is/are in a quiescent state with all affected commands finished and
|
||||
* others - blocked.
|
||||
*/
|
||||
spin_lock_irqsave(&res->sess->sess_list_lock, flags);
|
||||
list_add_tail(&res->sess_cmd_list_entry, &res->sess->sess_cmd_list);
|
||||
spin_unlock_irqrestore(&res->sess->sess_list_lock, flags);
|
||||
|
||||
scst_sess_get(res->sess);
|
||||
if (res->tgt_dev != NULL)
|
||||
res->cpu_cmd_counter = scst_get();
|
||||
@@ -4926,6 +4938,7 @@ EXPORT_SYMBOL_GPL(scst_write_same);
|
||||
int scst_finish_internal_cmd(struct scst_cmd *cmd)
|
||||
{
|
||||
int res;
|
||||
unsigned long flags;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
@@ -4938,6 +4951,17 @@ int scst_finish_internal_cmd(struct scst_cmd *cmd)
|
||||
goto out;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&cmd->sess->sess_list_lock, flags);
|
||||
list_del(&cmd->sess_cmd_list_entry);
|
||||
cmd->done = 1;
|
||||
cmd->finished = 1;
|
||||
spin_unlock_irqrestore(&cmd->sess->sess_list_lock, flags);
|
||||
|
||||
if (unlikely(test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags))) {
|
||||
scst_done_cmd_mgmt(cmd);
|
||||
scst_finish_cmd_mgmt(cmd);
|
||||
}
|
||||
|
||||
if (cmd->cdb[0] == REQUEST_SENSE)
|
||||
scst_complete_request_sense(cmd);
|
||||
else {
|
||||
|
||||
@@ -394,6 +394,7 @@ uint64_t scst_unpack_lun(const uint8_t *lun, int len);
|
||||
struct scst_mgmt_cmd *scst_alloc_mgmt_cmd(gfp_t gfp_mask);
|
||||
void scst_free_mgmt_cmd(struct scst_mgmt_cmd *mcmd);
|
||||
void scst_done_cmd_mgmt(struct scst_cmd *cmd);
|
||||
void scst_finish_cmd_mgmt(struct scst_cmd *cmd);
|
||||
|
||||
static inline void scst_devt_cleanup(struct scst_dev_type *devt) { }
|
||||
|
||||
|
||||
@@ -45,7 +45,6 @@
|
||||
|
||||
static void scst_cmd_set_sn(struct scst_cmd *cmd);
|
||||
static int __scst_init_cmd(struct scst_cmd *cmd);
|
||||
static void scst_finish_cmd_mgmt(struct scst_cmd *cmd);
|
||||
static struct scst_cmd *__scst_find_cmd_by_tag(struct scst_session *sess,
|
||||
uint64_t tag, bool to_abort);
|
||||
static void scst_process_redirect_cmd(struct scst_cmd *cmd,
|
||||
@@ -4703,7 +4702,7 @@ void scst_async_mcmd_completed(struct scst_mgmt_cmd *mcmd, int status)
|
||||
EXPORT_SYMBOL_GPL(scst_async_mcmd_completed);
|
||||
|
||||
/* No locks */
|
||||
static void scst_finish_cmd_mgmt(struct scst_cmd *cmd)
|
||||
void scst_finish_cmd_mgmt(struct scst_cmd *cmd)
|
||||
{
|
||||
struct scst_mgmt_cmd_stub *mstb, *t;
|
||||
bool wake = false;
|
||||
@@ -4846,9 +4845,6 @@ void scst_abort_cmd(struct scst_cmd *cmd, struct scst_mgmt_cmd *mcmd,
|
||||
*/
|
||||
smp_mb__after_set_bit();
|
||||
|
||||
if (cmd->internal)
|
||||
goto out;
|
||||
|
||||
if (cmd->tgt_dev == NULL) {
|
||||
spin_lock_irqsave(&scst_init_lock, flags);
|
||||
scst_init_poll_cnt++;
|
||||
@@ -4909,12 +4905,12 @@ void scst_abort_cmd(struct scst_cmd *cmd, struct scst_mgmt_cmd *mcmd,
|
||||
"sn %u) being executed/xmitted (state %d, "
|
||||
"op %x, proc time %ld sec., timeout %d sec.), "
|
||||
"deferring ABORT (cmd_done_wait_count %d, "
|
||||
"cmd_finish_wait_count %d)", cmd,
|
||||
"cmd_finish_wait_count %d, internal %d)", cmd,
|
||||
(long long unsigned int)cmd->tag,
|
||||
cmd->sn, cmd->state, cmd->cdb[0],
|
||||
(long)(jiffies - cmd->start_time) / HZ,
|
||||
cmd->timeout / HZ, mcmd->cmd_done_wait_count,
|
||||
mcmd->cmd_finish_wait_count);
|
||||
mcmd->cmd_finish_wait_count, cmd->internal);
|
||||
/*
|
||||
* cmd can't die here or sess_list_lock already taken
|
||||
* and cmd is in the sess list
|
||||
@@ -4926,14 +4922,13 @@ void scst_abort_cmd(struct scst_cmd *cmd, struct scst_mgmt_cmd *mcmd,
|
||||
mempool_free(mstb, scst_mgmt_stub_mempool);
|
||||
}
|
||||
|
||||
if (cmd->tgtt->on_abort_cmd)
|
||||
if (!cmd->internal && cmd->tgtt->on_abort_cmd)
|
||||
cmd->tgtt->on_abort_cmd(cmd);
|
||||
}
|
||||
|
||||
unlock:
|
||||
spin_unlock_irqrestore(&scst_mcmd_lock, flags);
|
||||
|
||||
out:
|
||||
tm_dbg_release_cmd(cmd);
|
||||
|
||||
TRACE_EXIT();
|
||||
@@ -6894,7 +6889,7 @@ static struct scst_cmd *__scst_find_cmd_by_tag(struct scst_session *sess,
|
||||
|
||||
list_for_each_entry(cmd, &sess->sess_cmd_list,
|
||||
sess_cmd_list_entry) {
|
||||
if (cmd->tag == tag) {
|
||||
if ((cmd->tag == tag) && likely(!cmd->internal)) {
|
||||
/*
|
||||
* We must not count done commands, because
|
||||
* they were submitted for transmission.
|
||||
@@ -6965,7 +6960,7 @@ struct scst_cmd *scst_find_cmd(struct scst_session *sess, void *data,
|
||||
*/
|
||||
if (cmd->done)
|
||||
continue;
|
||||
if (cmp_fn(cmd, data))
|
||||
if (cmp_fn(cmd, data) && likely(!cmd->internal))
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user