target: Make target_put_sess_cmd use target_release_cmd_kref
This patch moves target_put_sess_cmd() to use a se_cmd->cmd_kref callback target_release_cmd_kref when performing driver release of fabric->se_cmd descriptor memory. It sets the default cmd_kref count value to '2' within target_get_sess_cmd() setup, and currently assumes TFO->check_stop_free() usage. It drops se_tfo->check_release_cmd() usage in the main transport_release_cmd codepath. Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
This commit is contained in:
parent
ce136176fe
commit
7481deb413
|
@ -3349,13 +3349,13 @@ static void transport_release_cmd(struct se_cmd *cmd)
|
||||||
if (cmd->t_task_cdb != cmd->__t_task_cdb)
|
if (cmd->t_task_cdb != cmd->__t_task_cdb)
|
||||||
kfree(cmd->t_task_cdb);
|
kfree(cmd->t_task_cdb);
|
||||||
/*
|
/*
|
||||||
* Check if target_wait_for_sess_cmds() is expecting to
|
* If this cmd has been setup with target_get_sess_cmd(), drop
|
||||||
* release se_cmd directly here..
|
* the kref and call ->release_cmd() in kref callback.
|
||||||
*/
|
*/
|
||||||
if (cmd->check_release != 0 && cmd->se_tfo->check_release_cmd)
|
if (cmd->check_release != 0) {
|
||||||
if (cmd->se_tfo->check_release_cmd(cmd) != 0)
|
target_put_sess_cmd(cmd->se_sess, cmd);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
cmd->se_tfo->release_cmd(cmd);
|
cmd->se_tfo->release_cmd(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3915,6 +3915,9 @@ void target_get_sess_cmd(struct se_session *se_sess, struct se_cmd *se_cmd)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
kref_init(&se_cmd->cmd_kref);
|
||||||
|
kref_get(&se_cmd->cmd_kref);
|
||||||
|
|
||||||
spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
|
spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
|
||||||
list_add_tail(&se_cmd->se_cmd_list, &se_sess->sess_cmd_list);
|
list_add_tail(&se_cmd->se_cmd_list, &se_sess->sess_cmd_list);
|
||||||
se_cmd->check_release = 1;
|
se_cmd->check_release = 1;
|
||||||
|
@ -3922,30 +3925,36 @@ void target_get_sess_cmd(struct se_session *se_sess, struct se_cmd *se_cmd)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(target_get_sess_cmd);
|
EXPORT_SYMBOL(target_get_sess_cmd);
|
||||||
|
|
||||||
/* target_put_sess_cmd - Check for active I/O shutdown or list delete
|
static void target_release_cmd_kref(struct kref *kref)
|
||||||
* @se_sess: session to reference
|
|
||||||
* @se_cmd: command descriptor to drop
|
|
||||||
*/
|
|
||||||
int target_put_sess_cmd(struct se_session *se_sess, struct se_cmd *se_cmd)
|
|
||||||
{
|
{
|
||||||
|
struct se_cmd *se_cmd = container_of(kref, struct se_cmd, cmd_kref);
|
||||||
|
struct se_session *se_sess = se_cmd->se_sess;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
|
spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
|
||||||
if (list_empty(&se_cmd->se_cmd_list)) {
|
if (list_empty(&se_cmd->se_cmd_list)) {
|
||||||
spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
|
spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
|
||||||
WARN_ON(1);
|
WARN_ON(1);
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (se_sess->sess_tearing_down && se_cmd->cmd_wait_set) {
|
if (se_sess->sess_tearing_down && se_cmd->cmd_wait_set) {
|
||||||
spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
|
spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
|
||||||
complete(&se_cmd->cmd_wait_comp);
|
complete(&se_cmd->cmd_wait_comp);
|
||||||
return 1;
|
return;
|
||||||
}
|
}
|
||||||
list_del(&se_cmd->se_cmd_list);
|
list_del(&se_cmd->se_cmd_list);
|
||||||
spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
|
spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
|
||||||
|
|
||||||
return 0;
|
se_cmd->se_tfo->release_cmd(se_cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* target_put_sess_cmd - Check for active I/O shutdown via kref_put
|
||||||
|
* @se_sess: session to reference
|
||||||
|
* @se_cmd: command descriptor to drop
|
||||||
|
*/
|
||||||
|
int target_put_sess_cmd(struct se_session *se_sess, struct se_cmd *se_cmd)
|
||||||
|
{
|
||||||
|
return kref_put(&se_cmd->cmd_kref, target_release_cmd_kref);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(target_put_sess_cmd);
|
EXPORT_SYMBOL(target_put_sess_cmd);
|
||||||
|
|
||||||
|
|
|
@ -541,6 +541,7 @@ struct se_cmd {
|
||||||
struct list_head se_queue_node;
|
struct list_head se_queue_node;
|
||||||
struct list_head se_cmd_list;
|
struct list_head se_cmd_list;
|
||||||
struct completion cmd_wait_comp;
|
struct completion cmd_wait_comp;
|
||||||
|
struct kref cmd_kref;
|
||||||
struct target_core_fabric_ops *se_tfo;
|
struct target_core_fabric_ops *se_tfo;
|
||||||
int (*execute_task)(struct se_task *);
|
int (*execute_task)(struct se_task *);
|
||||||
void (*transport_complete_callback)(struct se_cmd *);
|
void (*transport_complete_callback)(struct se_cmd *);
|
||||||
|
|
Loading…
Reference in New Issue