On Fri, 2021-01-22 at 11:23 +0800, Ming Lei wrote: > > > > diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c > > index 2f162603876f..1c452a1c18fd 100644 > > --- a/drivers/scsi/hosts.c > > +++ b/drivers/scsi/hosts.c > > @@ -564,6 +564,8 @@ static bool scsi_host_check_in_flight(struct > > request *rq, void *data, > > int *count = data; > > struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq); > > > > + /* This pairs with set_bit() in scsi_host_queue_ready() */ > > + smp_mb__before_atomic(); > > So the above barrier orders atomic_read(&shost->host_blocked) and > test_bit()? Yes, I believe the change to SCMD_STATE_INFLIGHT should be visible before host_blocked is tested. For that, I would need to insert a full smb_mb() instead of smp_mb_after_atomic() below, though ... right? Which means that the smp_mb__before_atomic() above could be removed. The important thing is that if two threads execute scsi_host_queue_ready() simultaneously, one of them must see the SCMD_STATE_INFLIGHT bit of the other. Btw, I realized that calling scsi_host_busy() in scsi_host_queue_ready() is inefficient, because all we need to know there is whether the value is > 1; we don't need to iterate through the entire tag space. Thanks, Martin > > > if (test_bit(SCMD_STATE_INFLIGHT, &cmd->state)) > > (*count)++; > > > > diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c > > index b3f14f05340a..0a9a36c349ee 100644 > > --- a/drivers/scsi/scsi_lib.c > > +++ b/drivers/scsi/scsi_lib.c > > @@ -1353,8 +1353,12 @@ static inline int > > scsi_host_queue_ready(struct request_queue *q, > > if (scsi_host_in_recovery(shost)) > > return 0; > > > > + set_bit(SCMD_STATE_INFLIGHT, &cmd->state); > > + /* This pairs with test_bit() in > > scsi_host_check_in_flight() */ > > + smp_mb__after_atomic(); > > + > > if (atomic_read(&shost->host_blocked) > 0) { > > - if (scsi_host_busy(shost) > 0) > > + if (scsi_host_busy(shost) > 1) > > goto starved; > > > > /* > > @@ -1379,8 +1383,6 @@ static inline int > > scsi_host_queue_ready(struct request_queue *q, > > spin_unlock_irq(shost->host_lock); > > } > > > > - __set_bit(SCMD_STATE_INFLIGHT, &cmd->state); > > - > > Looks this patch fine. > > However, I'd suggest to confirm smartpqi's .can_queue usage first, > which > looks one big issue. >