On 10/15/2015 04:07 PM, Quinn Tran wrote:
QT> something like this. Piggy back on your fix.
core_tmr_drain_state_list()
{
while (!list_empty(&drain_task_list)) {
cmd = list_entry(drain_task_list.next, struct se_cmd, state_list);
list_del(&cmd->state_list);
----8<---
If ((cmd->t_state == TRANSPORT_COMPLETE) || (cmd->t_state ==
TRANSPORT_WRITE_PENDING) ||
(cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION)) {
// cmd is down at fabric layer. Send abort here because there is no other
callback.
If (cmd->t_state == TRANSPORT_WRITE_PENDING)
transport_cmd_check_stop_to_fabric();
cmd->se_tfo->aborted_task(cmd);
} else {
// cmd is at the back end. Aborted_task()/queue_status() will be sent at
transport_handle_abort()
target_stop_cmd();
}
---->8----
wait_for_completion(&cmd->finished);
target_put_sess_cmd(cmd);
}
}
Hello Quinn,
The above proposal introduces an aborted_task() call in the TMR context,
which is something I really would like to avoid. Calling aborted_task()
from the command execution context has the advantage that it is
guaranteed that that call cannot race with other back-end driver
callback functions. Are you sure that an additional aborted_task() call
is needed ? The target core checks the CMD_T_ABORTED flag in
target_execute_cmd() and in target_complete_cmd(). But even if the
former function skips execution because the CMD_T_ABORTED flag has been
set the latter function is still executed. This is why I think that a
single call to transport_handle_abort() in target_complete_cmd() is
sufficient.
Bart.
--
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