> index 5d83a162d03b..c1d5e4e36125 100644
> --- a/drivers/scsi/scsi_lib.c
> +++ b/drivers/scsi/scsi_lib.c
> @@ -1635,8 +1635,11 @@ static blk_status_t scsi_mq_prep_fn(struct request
> *req)
>
> static void scsi_mq_done(struct scsi_cmnd *cmd)
> {
> + if (unlikely(test_and_set_bit(__SCMD_COMPLETE, &cmd->flags)))
> + return;
> trace_scsi_dispatch_cmd_done(cmd);
> - blk_mq_complete_request(cmd->request);
> + if (unlikely(!blk_mq_complete_request(cmd->request)))
> + clear_bit(__SCMD_COMPLETE, &cmd->flags);
> }
This looks a little odd to me. If we didn't complete the command
someone else did. Why would we clear the bit in this case?
> static void scsi_mq_put_budget(struct blk_mq_hw_ctx *hctx)
> @@ -1701,6 +1704,7 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx
> *hctx,
> goto out_dec_host_busy;
> req->rq_flags |= RQF_DONTPREP;
> } else {
> + cmd->flags &= ~SCMD_COMPLETE;
> blk_mq_start_request(req);
> }
>
> diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
> index d6fd2aba0380..ded7c7194a28 100644
> --- a/include/scsi/scsi_cmnd.h
> +++ b/include/scsi/scsi_cmnd.h
> @@ -58,6 +58,9 @@ struct scsi_pointer {
> #define SCMD_TAGGED (1 << 0)
> #define SCMD_UNCHECKED_ISA_DMA (1 << 1)
> #define SCMD_INITIALIZED (1 << 2)
> +
> +#define __SCMD_COMPLETE 3
> +#define SCMD_COMPLETE (1 << __SCMD_COMPLETE)
This mixing of atomic and non-atomic bitops looks rather dangerous
to me. Can you add a new atomic_flags just for the completed flag,
and always use the bitops on it for now? I think we can eventually
kill most of the existing flags except for SCMD_TAGGED over the
next merge window or two and then move that over as well.
Otherwise the concept looks fine to me.