@@ -1220,7 +1220,6 @@ void transport_init_se_cmd(
INIT_LIST_HEAD(&cmd->se_cmd_list);
INIT_LIST_HEAD(&cmd->state_list);
init_completion(&cmd->t_transport_stop_comp);
- init_completion(&cmd->cmd_wait_comp);
spin_lock_init(&cmd->t_state_lock);
kref_init(&cmd->cmd_kref);
kref_init(&cmd->tgt_ref);
@@ -2534,8 +2533,8 @@ int transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks)
*/
if (aborted) {
pr_debug("Detected CMD_T_ABORTED for ITT: %llu\n", cmd->tag);
- wait_for_completion(&cmd->cmd_wait_comp);
- cmd->se_tfo->release_cmd(cmd);
+ wait_for_completion(&cmd->complete);
+ transport_put_cmd(cmd);
ret = 1;
}
return ret;
@@ -2612,7 +2611,6 @@ static void target_release_cmd_kref(struct kref *kref)
list_del_init(&se_cmd->se_cmd_list);
spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
target_free_cmd_mem(se_cmd);
- complete(&se_cmd->cmd_wait_comp);
return;
}
list_del_init(&se_cmd->se_cmd_list);
@@ -2652,9 +2650,8 @@ int target_put_sess_cmd(struct se_cmd *se_cmd)
}
EXPORT_SYMBOL(target_put_sess_cmd);
-/* target_sess_cmd_list_set_waiting - Flag all commands in
- * sess_cmd_list to complete cmd_wait_comp. Set
- * sess_tearing_down so no more commands are queued.
+/**
+ * target_sess_cmd_list_set_waiting - prevent new commands to be queued
* @se_sess: session to flag
*/
void target_sess_cmd_list_set_waiting(struct se_session *se_sess)
@@ -2711,12 +2708,13 @@ void target_wait_for_sess_cmds(struct se_session *se_sess)
target_put_sess_cmd(se_cmd);
}
- wait_for_completion(&se_cmd->cmd_wait_comp);
- pr_debug("After cmd_wait_comp: se_cmd: %p t_state: %d"
- " fabric state: %d\n", se_cmd, se_cmd->t_state,
- se_cmd->se_tfo->get_cmd_state(se_cmd));
+ wait_for_completion(&se_cmd->complete);
+ pr_debug("Finished waiting for se_cmd %p t_state %d fabric state: %d\n",
+ se_cmd, se_cmd->t_state,
+ se_cmd->se_tfo->get_cmd_state(se_cmd));
- se_cmd->se_tfo->release_cmd(se_cmd);
+ WARN_ON_ONCE(!se_cmd->se_sess);
+ target_put_sess_cmd(se_cmd);
}
spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
@@ -473,7 +473,6 @@ struct se_cmd {
struct se_session *se_sess;
struct se_tmr_req *se_tmr_req;
struct list_head se_cmd_list;
- struct completion cmd_wait_comp;
const struct target_core_fabric_ops *se_tfo;
sense_reason_t (*execute_cmd)(struct se_cmd *);
sense_reason_t (*transport_complete_callback)(struct se_cmd *, bool, int *);
Use the se_cmd reference counting mechanism instead of calling the .release_cmd() method directly. Switch from 'cmd_wait_comp' to 'complete' to avoid triggering a circular dependency. Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com> Cc: Hannes Reinecke <hare@suse.com> Cc: Christoph Hellwig <hch@lst.de> Cc: Andy Grover <agrover@redhat.com> Cc: David Disseldorp <ddiss@suse.de> --- drivers/target/target_core_transport.c | 22 ++++++++++------------ include/target/target_core_base.h | 1 - 2 files changed, 10 insertions(+), 13 deletions(-)