Re: [PATCH 06/21] target: Rework abort and LUN reset handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, May 20, 2015 at 02:52:25PM +0200, Bart Van Assche wrote:
> Instead of invoking target driver callback functions from the
> context that handles an abort or LUN reset task management function,
> only set the abort flag from that context and perform the actual
> abort handling from the context of the regular command processing
> flow. This approach has the following advantages:
> - The task management function code becomes much easier to read and
>   to verify since the number of potential race conditions against
>   the command processing flow is strongly reduced.
> - It is no longer needed to store the command state into the command
>   itself since that information is no longer needed from the context
>   where a task management function is processed.

I like this in general, but you should also mention that this means any
queued command will now be executed.  I think that makes sense for
any command already beeing processed in some way as aborting it out
of that complicated setup has the problems mention above.  I think it
might make sense to still cancel anything that is in the workqueue
before entering the real target processing.  But for that we'd need
a version of cancel_delayed_work that works on regular work structures.

> +/**
> + * __target_abort_cmd - set abort flag if it has not yet been set
> + * @cmd:	Command to be aborted.
> + * @tmr_nacl:	Node ACL through which the task management function had been
> + *		received. NULL if TASK ABORT STATUS has not been set.
> + * @uncond_cb:  Whether to call the callback function upon command completion
> + *              if the abort flag had already been set.
> + * @done:	Callback function to be called upon command completion.
> + * @done_arg:	Argument to be passed to the function @done.
> + */
> +static bool __target_abort_cmd(struct se_cmd *cmd, struct se_node_acl *tmr_nacl,
> +			       bool uncond_cb, void (*done)(void *),
> +			       void *done_arg)
> +{
> +	bool ret = false;
> +
> +	lockdep_assert_held(&cmd->t_state_lock);

I think this function should get the abort_ctx pased n a properly typed
way and also increment the command count.  The done argument isn't needed
either as it's alwasy the same.  Also it might make sense to move
the logic to find the tmr_nacl into this function as well.

With all that we'll have a much simpler function signature and don't need
the return value at all.

> +static void target_finish_abort(struct cmd_abort_ctx *ctx, const char *action,
> +				void (*show)(void *), void *arg)
> +{
> +	target_cmd_abort_done(ctx);
> +	while (wait_for_completion_interruptible_timeout(&ctx->done, 30 * HZ)
> +	       <= 0) {
> +		pr_info("%s: waiting for %d commands to finish\n", action,
> +			atomic_read(&ctx->cmd_count));
> +		if (show)
> +			show(arg);
> +	}

Might be better to just open code this function in the callers, there
is very little code and a huge variance in arguments.

>  void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status)
>  {
>  	struct se_device *dev = cmd->se_dev;
>  	int success = scsi_status == GOOD;
>  	unsigned long flags;
>  
> -	cmd->scsi_status = scsi_status;
> -
> +	if (cmd->transport_state & CMD_T_ABORTED) {
> +		transport_handle_abort(cmd);
> +		return;
> +	}

Do we really want to call transport_handle_abort from irq context?
I think it should be called from workqueue context like all the
other completion functionality.

--
To unsubscribe from this list: send the line "unsubscribe target-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux SCSI]     [Kernel Newbies]     [Linux SCSI Target Infrastructure]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Device Mapper]

  Powered by Linux