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: Nicholas Bellinger <nab@linux-iscsi.org>
This commit is contained in:
Родитель
9b31a328e3
Коммит
1d19f7800d
|
@ -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)
|
||||||
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)
|
||||||
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 {
|
||||||
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Загрузка…
Ссылка в новой задаче