Commit 1d19f780 authored by Nicholas Bellinger's avatar Nicholas Bellinger

ib_srpt: Call target_sess_cmd_list_set_waiting during shutdown_session

Given that srpt_release_channel_work() calls target_wait_for_sess_cmds()
to allow outstanding se_cmd_t->cmd_kref a change to complete, the call
to perform target_sess_cmd_list_set_waiting() needs to happen in
srpt_shutdown_session()

Also, this patch adds an explicit call to srpt_shutdown_session() within
srpt_drain_channel() so that target_sess_cmd_list_set_waiting() will be
called in the cases where TFO->shutdown_session() is not triggered
directly by TCM.

Cc: Joern Engel <joern@logfs.org>
Cc: Roland Dreier <roland@kernel.org>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent 9b31a328
...@@ -2226,6 +2226,27 @@ static void srpt_close_ch(struct srpt_rdma_ch *ch) ...@@ -2226,6 +2226,27 @@ static void srpt_close_ch(struct srpt_rdma_ch *ch)
spin_unlock_irq(&sdev->spinlock); spin_unlock_irq(&sdev->spinlock);
} }
/**
* srpt_shutdown_session() - Whether or not a session may be shut down.
*/
static int srpt_shutdown_session(struct se_session *se_sess)
{
struct srpt_rdma_ch *ch = se_sess->fabric_sess_ptr;
unsigned long flags;
spin_lock_irqsave(&ch->spinlock, flags);
if (ch->in_shutdown) {
spin_unlock_irqrestore(&ch->spinlock, flags);
return true;
}
ch->in_shutdown = true;
target_sess_cmd_list_set_waiting(se_sess);
spin_unlock_irqrestore(&ch->spinlock, flags);
return true;
}
/** /**
* srpt_drain_channel() - Drain a channel by resetting the IB queue pair. * srpt_drain_channel() - Drain a channel by resetting the IB queue pair.
* @cm_id: Pointer to the CM ID of the channel to be drained. * @cm_id: Pointer to the CM ID of the channel to be drained.
...@@ -2264,6 +2285,9 @@ static void srpt_drain_channel(struct ib_cm_id *cm_id) ...@@ -2264,6 +2285,9 @@ static void srpt_drain_channel(struct ib_cm_id *cm_id)
spin_unlock_irq(&sdev->spinlock); spin_unlock_irq(&sdev->spinlock);
if (do_reset) { if (do_reset) {
if (ch->sess)
srpt_shutdown_session(ch->sess);
ret = srpt_ch_qp_err(ch); ret = srpt_ch_qp_err(ch);
if (ret < 0) if (ret < 0)
printk(KERN_ERR "Setting queue pair in error state" printk(KERN_ERR "Setting queue pair in error state"
...@@ -3466,14 +3490,6 @@ static void srpt_release_cmd(struct se_cmd *se_cmd) ...@@ -3466,14 +3490,6 @@ static void srpt_release_cmd(struct se_cmd *se_cmd)
spin_unlock_irqrestore(&ch->spinlock, flags); spin_unlock_irqrestore(&ch->spinlock, flags);
} }
/**
* srpt_shutdown_session() - Whether or not a session may be shut down.
*/
static int srpt_shutdown_session(struct se_session *se_sess)
{
return true;
}
/** /**
* srpt_close_session() - Forcibly close a session. * srpt_close_session() - Forcibly close a session.
* *
......
...@@ -325,6 +325,7 @@ struct srpt_rdma_ch { ...@@ -325,6 +325,7 @@ struct srpt_rdma_ch {
u8 sess_name[36]; u8 sess_name[36];
struct work_struct release_work; struct work_struct release_work;
struct completion *release_done; struct completion *release_done;
bool in_shutdown;
}; };
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment