Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cdbb70bb authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Nicholas Bellinger
Browse files

target: factor some duplicate code for stopping a task

parent 0c2cfe5f
Loading
Loading
Loading
Loading
+2 −17
Original line number Diff line number Diff line
@@ -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",
@@ -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);
		target_stop_task(task, &flags);

		if (!atomic_dec_and_test(&cmd->t_task_cdbs_ex_left)) {
			spin_unlock_irqrestore(&cmd->t_state_lock, flags);
+28 −19
Original line number Diff line number Diff line
@@ -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;
@@ -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);

+1 −0
Original line number Diff line number Diff line
@@ -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);