mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-21 20:51:27 +00:00
scst: Switch to thread context before executing a reservation command
Persistent reservation commands need thread context because scst_pr_is_cmd_allowed() locks the PR mutex. Reservation commands either need BH or thread context. Hence switch from atomic to thread context before processing such commands. Reported-by: Shahar Salzman <shahar.salzman@kaminario.com> Signed-off-by: Bart Van Assche <bvanassche@acm.org> git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@5963 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -1594,12 +1594,44 @@ void scst_rx_data(struct scst_cmd *cmd, int status,
|
||||
}
|
||||
EXPORT_SYMBOL(scst_rx_data);
|
||||
|
||||
/*
|
||||
* Whether a command must be executed in thread context. Persistent reservation
|
||||
* commands need thread context because of dev_pr_mutex. Traditional reserve
|
||||
* and release commands need thread context because e.g. queueing a unit
|
||||
* attention needs either BH or thread context.
|
||||
*/
|
||||
static inline bool scst_needs_thread_context(struct scst_cmd *cmd)
|
||||
{
|
||||
switch (cmd->cdb[0]) {
|
||||
case PERSISTENT_RESERVE_IN:
|
||||
case PERSISTENT_RESERVE_OUT:
|
||||
case RESERVE:
|
||||
case RESERVE_10:
|
||||
case RELEASE:
|
||||
case RELEASE_10:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int scst_tgt_pre_exec(struct scst_cmd *cmd)
|
||||
{
|
||||
int res = SCST_CMD_STATE_RES_CONT_SAME, rc;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
/* Switch to thread context before executing a reservation command. */
|
||||
if (unlikely(scst_cmd_atomic(cmd) &&
|
||||
((cmd->dev && cmd->dev->pr_is_set) ||
|
||||
scst_needs_thread_context(cmd)))) {
|
||||
TRACE_DBG("Atomic context and %s, rescheduling (cmd %p)",
|
||||
cmd->dev && cmd->dev->pr_is_set ?
|
||||
"dev->pr_is_set" : "reservation command", cmd);
|
||||
res = SCST_CMD_STATE_RES_NEED_THREAD;
|
||||
goto out;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
|
||||
if (unlikely(trace_flag & TRACE_DATA_RECEIVED) &&
|
||||
(cmd->data_direction & SCST_DATA_WRITE)) {
|
||||
|
||||
Reference in New Issue
Block a user