Skip to content

Commit

Permalink
target: Make target_put_sess_cmd use target_release_cmd_kref
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Nicholas Bellinger committed Dec 14, 2011
1 parent ce13617 commit 7481deb
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 15 deletions.
39 changes: 24 additions & 15 deletions drivers/target/target_core_transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -3349,13 +3349,13 @@ static void transport_release_cmd(struct se_cmd *cmd)
if (cmd->t_task_cdb != cmd->__t_task_cdb)
kfree(cmd->t_task_cdb);
/*
* Check if target_wait_for_sess_cmds() is expecting to
* release se_cmd directly here..
* If this cmd has been setup with target_get_sess_cmd(), drop
* the kref and call ->release_cmd() in kref callback.
*/
if (cmd->check_release != 0 && cmd->se_tfo->check_release_cmd)
if (cmd->se_tfo->check_release_cmd(cmd) != 0)
return;

if (cmd->check_release != 0) {
target_put_sess_cmd(cmd->se_sess, cmd);
return;
}
cmd->se_tfo->release_cmd(cmd);
}

Expand Down Expand Up @@ -3915,37 +3915,46 @@ void target_get_sess_cmd(struct se_session *se_sess, struct se_cmd *se_cmd)
{
unsigned long flags;

kref_init(&se_cmd->cmd_kref);
kref_get(&se_cmd->cmd_kref);

spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
list_add_tail(&se_cmd->se_cmd_list, &se_sess->sess_cmd_list);
se_cmd->check_release = 1;
spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
}
EXPORT_SYMBOL(target_get_sess_cmd);

/* target_put_sess_cmd - Check for active I/O shutdown or list delete
* @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)
static void target_release_cmd_kref(struct kref *kref)
{
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;

spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
if (list_empty(&se_cmd->se_cmd_list)) {
spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
WARN_ON(1);
return 0;
return;
}

if (se_sess->sess_tearing_down && se_cmd->cmd_wait_set) {
spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
complete(&se_cmd->cmd_wait_comp);
return 1;
return;
}
list_del(&se_cmd->se_cmd_list);
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);

Expand Down
1 change: 1 addition & 0 deletions include/target/target_core_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,7 @@ struct se_cmd {
struct list_head se_queue_node;
struct list_head se_cmd_list;
struct completion cmd_wait_comp;
struct kref cmd_kref;
struct target_core_fabric_ops *se_tfo;
int (*execute_task)(struct se_task *);
void (*transport_complete_callback)(struct se_cmd *);
Expand Down

0 comments on commit 7481deb

Please sign in to comment.