Skip to content

Commit

Permalink
target: factor some duplicate code for stopping a task
Browse files Browse the repository at this point in the history
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
  • Loading branch information
Christoph Hellwig authored and Nicholas Bellinger committed Oct 24, 2011
1 parent 0c2cfe5 commit cdbb70b
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 36 deletions.
19 changes: 2 additions & 17 deletions drivers/target/target_core_tmr.c
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,6 @@ static void core_tmr_drain_task_list(
list_del(&task->t_state_list);
cmd = task->task_se_cmd;

spin_lock_irqsave(&cmd->t_state_lock, flags);
pr_debug("LUN_RESET: %s cmd: %p task: %p"
" ITT/CmdSN: 0x%08x/0x%08x, i_state: %d, t_state/"
"def_t_state: %d/%d cdb: 0x%02x\n",
Expand All @@ -256,22 +255,8 @@ static void core_tmr_drain_task_list(
atomic_read(&cmd->t_transport_stop),
atomic_read(&cmd->t_transport_sent));

if (task->task_flags & TF_ACTIVE) {
task->task_flags |= TF_REQUEST_STOP;
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);
spin_lock_irqsave(&cmd->t_state_lock, flags);
target_stop_task(task, &flags);

if (!atomic_dec_and_test(&cmd->t_task_cdbs_ex_left)) {
spin_unlock_irqrestore(&cmd->t_state_lock, flags);
Expand Down
47 changes: 28 additions & 19 deletions drivers/target/target_core_transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -1762,6 +1762,33 @@ void 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)
{
struct se_task *task, *task_tmp;
Expand Down Expand Up @@ -1793,28 +1820,10 @@ static int transport_stop_tasks_for_cmd(struct se_cmd *cmd)
continue;
}

/*
* 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 {
if (!target_stop_task(task, &flags)) {
pr_debug("Task %p - did nothing\n", task);
ret++;
}

__transport_stop_task_timer(task, &flags);
}
spin_unlock_irqrestore(&cmd->t_state_lock, flags);

Expand Down
1 change: 1 addition & 0 deletions include/target/target_core_transport.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ extern int transport_generic_handle_data(struct se_cmd *);
extern void transport_new_cmd_failure(struct se_cmd *);
extern int transport_generic_handle_tmr(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 int transport_generic_map_mem_to_cmd(struct se_cmd *cmd, struct scatterlist *, u32,
struct scatterlist *, u32);
Expand Down

0 comments on commit cdbb70b

Please sign in to comment.