diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index f737e0609..f64acb7a9 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -3664,11 +3664,11 @@ static int scst_pre_xmit_response1(struct scst_cmd *cmd) /* * Those counters protect from not getting too long processing * latency, so we should decrement them after cmd completed. + * + * @cmd processing for SCST device is complete. */ - smp_mb__before_atomic_dec(); WARN_ON_ONCE(!cmd->owns_refcnt); cmd->owns_refcnt = false; - atomic_dec(&cmd->tgt_dev->tgt_dev_cmd_count); percpu_ref_put(&cmd->dev->refcnt); #ifdef CONFIG_SCST_PER_DEVICE_CMD_COUNT_LIMIT atomic_dec(&cmd->dev->dev_cmd_count); @@ -3875,6 +3875,22 @@ static int scst_finish_cmd(struct scst_cmd *cmd) } } + if (likely(cmd->tgt_dev != NULL)) { + /* + * We must decrement @tgt_dev->tgt_dev_cmd_count + * after scst_tgt_cmd_done() was called. Otherwise, + * this may lead to a race condition between + * scst_acg_repl_lun() and scst_tgt_cmd_done()'s + * cmd processing. + * + * See also https://github.com/SCST-project/scst/pull/27 + * + * @cmd processing for target device is complete. + */ + smp_mb__before_atomic_dec(); + atomic_dec(&cmd->tgt_dev->tgt_dev_cmd_count); + } + atomic_dec(&sess->sess_cmd_count); spin_lock_irq(&sess->sess_list_lock);