mirror of https://gitee.com/openkylin/linux.git
target: factor some duplicate code for stopping a task
Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
This commit is contained in:
parent
0c2cfe5fe7
commit
cdbb70bb4c
|
@ -236,7 +236,6 @@ static void core_tmr_drain_task_list(
|
||||||
list_del(&task->t_state_list);
|
list_del(&task->t_state_list);
|
||||||
cmd = task->task_se_cmd;
|
cmd = task->task_se_cmd;
|
||||||
|
|
||||||
spin_lock_irqsave(&cmd->t_state_lock, flags);
|
|
||||||
pr_debug("LUN_RESET: %s cmd: %p task: %p"
|
pr_debug("LUN_RESET: %s cmd: %p task: %p"
|
||||||
" ITT/CmdSN: 0x%08x/0x%08x, i_state: %d, t_state/"
|
" ITT/CmdSN: 0x%08x/0x%08x, i_state: %d, t_state/"
|
||||||
"def_t_state: %d/%d cdb: 0x%02x\n",
|
"def_t_state: %d/%d cdb: 0x%02x\n",
|
||||||
|
@ -256,22 +255,8 @@ static void core_tmr_drain_task_list(
|
||||||
atomic_read(&cmd->t_transport_stop),
|
atomic_read(&cmd->t_transport_stop),
|
||||||
atomic_read(&cmd->t_transport_sent));
|
atomic_read(&cmd->t_transport_sent));
|
||||||
|
|
||||||
if (task->task_flags & TF_ACTIVE) {
|
spin_lock_irqsave(&cmd->t_state_lock, flags);
|
||||||
task->task_flags |= TF_REQUEST_STOP;
|
target_stop_task(task, &flags);
|
||||||
spin_unlock_irqrestore(
|
|
||||||
&cmd->t_state_lock, flags);
|
|
||||||
|
|
||||||
pr_debug("LUN_RESET: Waiting for task: %p to shutdown"
|
|
||||||
" for dev: %p\n", task, dev);
|
|
||||||
wait_for_completion(&task->task_stop_comp);
|
|
||||||
pr_debug("LUN_RESET Completed task: %p shutdown for"
|
|
||||||
" dev: %p\n", task, dev);
|
|
||||||
|
|
||||||
spin_lock_irqsave(&cmd->t_state_lock, flags);
|
|
||||||
atomic_dec(&cmd->t_task_cdbs_left);
|
|
||||||
task->task_flags &= ~(TF_ACTIVE | TF_REQUEST_STOP);
|
|
||||||
}
|
|
||||||
__transport_stop_task_timer(task, &flags);
|
|
||||||
|
|
||||||
if (!atomic_dec_and_test(&cmd->t_task_cdbs_ex_left)) {
|
if (!atomic_dec_and_test(&cmd->t_task_cdbs_ex_left)) {
|
||||||
spin_unlock_irqrestore(&cmd->t_state_lock, flags);
|
spin_unlock_irqrestore(&cmd->t_state_lock, flags);
|
||||||
|
|
|
@ -1762,6 +1762,33 @@ void transport_generic_free_cmd_intr(
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(transport_generic_free_cmd_intr);
|
EXPORT_SYMBOL(transport_generic_free_cmd_intr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the task is active, request it to be stopped and sleep until it
|
||||||
|
* has completed.
|
||||||
|
*/
|
||||||
|
bool target_stop_task(struct se_task *task, unsigned long *flags)
|
||||||
|
{
|
||||||
|
struct se_cmd *cmd = task->task_se_cmd;
|
||||||
|
bool was_active = false;
|
||||||
|
|
||||||
|
if (task->task_flags & TF_ACTIVE) {
|
||||||
|
task->task_flags |= TF_REQUEST_STOP;
|
||||||
|
spin_unlock_irqrestore(&cmd->t_state_lock, *flags);
|
||||||
|
|
||||||
|
pr_debug("Task %p waiting to complete\n", task);
|
||||||
|
wait_for_completion(&task->task_stop_comp);
|
||||||
|
pr_debug("Task %p stopped successfully\n", task);
|
||||||
|
|
||||||
|
spin_lock_irqsave(&cmd->t_state_lock, *flags);
|
||||||
|
atomic_dec(&cmd->t_task_cdbs_left);
|
||||||
|
task->task_flags &= ~(TF_ACTIVE | TF_REQUEST_STOP);
|
||||||
|
was_active = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
__transport_stop_task_timer(task, flags);
|
||||||
|
return was_active;
|
||||||
|
}
|
||||||
|
|
||||||
static int transport_stop_tasks_for_cmd(struct se_cmd *cmd)
|
static int transport_stop_tasks_for_cmd(struct se_cmd *cmd)
|
||||||
{
|
{
|
||||||
struct se_task *task, *task_tmp;
|
struct se_task *task, *task_tmp;
|
||||||
|
@ -1793,28 +1820,10 @@ static int transport_stop_tasks_for_cmd(struct se_cmd *cmd)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
if (!target_stop_task(task, &flags)) {
|
||||||
* If the struct se_task is active, sleep until it is returned
|
|
||||||
* from the plugin.
|
|
||||||
*/
|
|
||||||
if (task->task_flags & TF_ACTIVE) {
|
|
||||||
task->task_flags |= TF_REQUEST_STOP;
|
|
||||||
spin_unlock_irqrestore(&cmd->t_state_lock,
|
|
||||||
flags);
|
|
||||||
|
|
||||||
pr_debug("Task %p waiting to complete\n", task);
|
|
||||||
wait_for_completion(&task->task_stop_comp);
|
|
||||||
pr_debug("Task %p stopped successfully\n", task);
|
|
||||||
|
|
||||||
spin_lock_irqsave(&cmd->t_state_lock, flags);
|
|
||||||
atomic_dec(&cmd->t_task_cdbs_left);
|
|
||||||
task->task_flags &= ~(TF_ACTIVE | TF_REQUEST_STOP);
|
|
||||||
} else {
|
|
||||||
pr_debug("Task %p - did nothing\n", task);
|
pr_debug("Task %p - did nothing\n", task);
|
||||||
ret++;
|
ret++;
|
||||||
}
|
}
|
||||||
|
|
||||||
__transport_stop_task_timer(task, &flags);
|
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&cmd->t_state_lock, flags);
|
spin_unlock_irqrestore(&cmd->t_state_lock, flags);
|
||||||
|
|
||||||
|
|
|
@ -171,6 +171,7 @@ extern int transport_generic_handle_data(struct se_cmd *);
|
||||||
extern void transport_new_cmd_failure(struct se_cmd *);
|
extern void transport_new_cmd_failure(struct se_cmd *);
|
||||||
extern int transport_generic_handle_tmr(struct se_cmd *);
|
extern int transport_generic_handle_tmr(struct se_cmd *);
|
||||||
extern void transport_generic_free_cmd_intr(struct se_cmd *);
|
extern void transport_generic_free_cmd_intr(struct se_cmd *);
|
||||||
|
extern bool target_stop_task(struct se_task *task, unsigned long *flags);
|
||||||
extern void __transport_stop_task_timer(struct se_task *, unsigned long *);
|
extern void __transport_stop_task_timer(struct se_task *, unsigned long *);
|
||||||
extern int transport_generic_map_mem_to_cmd(struct se_cmd *cmd, struct scatterlist *, u32,
|
extern int transport_generic_map_mem_to_cmd(struct se_cmd *cmd, struct scatterlist *, u32,
|
||||||
struct scatterlist *, u32);
|
struct scatterlist *, u32);
|
||||||
|
|
Loading…
Reference in New Issue