mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-24 07:31:41 +00:00
scsi: target: Simplify the code for waiting for command completion
Instead of embedding the completion that is used for waiting for command completion in struct se_cmd, let the context that waits for command completion allocate it. This makes it possible to have a single code path for non-aborted and aborted commands in target_release_cmd_kref() and avoids that transport_generic_free_cmd() has to call cmd->se_tfo->release_cmd() directly. This patch does not change any functionality. Note: transport_generic_free_cmd() only waits until the se_cmd reference count has reached zero after it has set both CMD_T_FABRIC_STOP and CMD_T_ABORTED. Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com> Reviewed-by: Mike Christie <mchristi@redhat.com> Cc: Hannes Reinecke <hare@suse.com> Cc: Christoph Hellwig <hch@lst.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
edf46eee59
commit
7b2cc7dc0d
2 changed files with 9 additions and 17 deletions
|
@ -1309,7 +1309,7 @@ void transport_init_se_cmd(
|
||||||
INIT_LIST_HEAD(&cmd->se_cmd_list);
|
INIT_LIST_HEAD(&cmd->se_cmd_list);
|
||||||
INIT_LIST_HEAD(&cmd->state_list);
|
INIT_LIST_HEAD(&cmd->state_list);
|
||||||
init_completion(&cmd->t_transport_stop_comp);
|
init_completion(&cmd->t_transport_stop_comp);
|
||||||
init_completion(&cmd->cmd_wait_comp);
|
cmd->compl = NULL;
|
||||||
spin_lock_init(&cmd->t_state_lock);
|
spin_lock_init(&cmd->t_state_lock);
|
||||||
INIT_WORK(&cmd->work, NULL);
|
INIT_WORK(&cmd->work, NULL);
|
||||||
kref_init(&cmd->cmd_kref);
|
kref_init(&cmd->cmd_kref);
|
||||||
|
@ -2658,6 +2658,7 @@ static void target_wait_free_cmd(struct se_cmd *cmd, bool *aborted, bool *tas)
|
||||||
*/
|
*/
|
||||||
int transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks)
|
int transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks)
|
||||||
{
|
{
|
||||||
|
DECLARE_COMPLETION_ONSTACK(compl);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
bool aborted = false, tas = false;
|
bool aborted = false, tas = false;
|
||||||
|
|
||||||
|
@ -2676,12 +2677,13 @@ int transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks)
|
||||||
if (cmd->se_lun)
|
if (cmd->se_lun)
|
||||||
transport_lun_remove_cmd(cmd);
|
transport_lun_remove_cmd(cmd);
|
||||||
}
|
}
|
||||||
|
if (aborted)
|
||||||
|
cmd->compl = &compl;
|
||||||
if (!aborted || tas)
|
if (!aborted || tas)
|
||||||
ret = target_put_sess_cmd(cmd);
|
ret = target_put_sess_cmd(cmd);
|
||||||
if (aborted) {
|
if (aborted) {
|
||||||
pr_debug("Detected CMD_T_ABORTED for ITT: %llu\n", cmd->tag);
|
pr_debug("Detected CMD_T_ABORTED for ITT: %llu\n", cmd->tag);
|
||||||
wait_for_completion(&cmd->cmd_wait_comp);
|
wait_for_completion(&compl);
|
||||||
cmd->se_tfo->release_cmd(cmd);
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -2742,31 +2744,21 @@ static void target_release_cmd_kref(struct kref *kref)
|
||||||
{
|
{
|
||||||
struct se_cmd *se_cmd = container_of(kref, struct se_cmd, cmd_kref);
|
struct se_cmd *se_cmd = container_of(kref, struct se_cmd, cmd_kref);
|
||||||
struct se_session *se_sess = se_cmd->se_sess;
|
struct se_session *se_sess = se_cmd->se_sess;
|
||||||
|
struct completion *compl = se_cmd->compl;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
bool fabric_stop;
|
|
||||||
|
|
||||||
if (se_sess) {
|
if (se_sess) {
|
||||||
spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
|
spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
|
||||||
list_del_init(&se_cmd->se_cmd_list);
|
list_del_init(&se_cmd->se_cmd_list);
|
||||||
if (list_empty(&se_sess->sess_cmd_list))
|
if (list_empty(&se_sess->sess_cmd_list))
|
||||||
wake_up(&se_sess->cmd_list_wq);
|
wake_up(&se_sess->cmd_list_wq);
|
||||||
|
|
||||||
spin_lock(&se_cmd->t_state_lock);
|
|
||||||
fabric_stop = (se_cmd->transport_state & CMD_T_FABRIC_STOP) &&
|
|
||||||
(se_cmd->transport_state & CMD_T_ABORTED);
|
|
||||||
spin_unlock(&se_cmd->t_state_lock);
|
|
||||||
|
|
||||||
if (fabric_stop) {
|
|
||||||
spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
|
|
||||||
target_free_cmd_mem(se_cmd);
|
|
||||||
complete(&se_cmd->cmd_wait_comp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
|
spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
target_free_cmd_mem(se_cmd);
|
target_free_cmd_mem(se_cmd);
|
||||||
se_cmd->se_tfo->release_cmd(se_cmd);
|
se_cmd->se_tfo->release_cmd(se_cmd);
|
||||||
|
if (compl)
|
||||||
|
complete(compl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -475,7 +475,7 @@ struct se_cmd {
|
||||||
struct se_session *se_sess;
|
struct se_session *se_sess;
|
||||||
struct se_tmr_req *se_tmr_req;
|
struct se_tmr_req *se_tmr_req;
|
||||||
struct list_head se_cmd_list;
|
struct list_head se_cmd_list;
|
||||||
struct completion cmd_wait_comp;
|
struct completion *compl;
|
||||||
const struct target_core_fabric_ops *se_tfo;
|
const struct target_core_fabric_ops *se_tfo;
|
||||||
sense_reason_t (*execute_cmd)(struct se_cmd *);
|
sense_reason_t (*execute_cmd)(struct se_cmd *);
|
||||||
sense_reason_t (*transport_complete_callback)(struct se_cmd *, bool, int *);
|
sense_reason_t (*transport_complete_callback)(struct se_cmd *, bool, int *);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue