On 2020-07-05 23:22, Hannes Reinecke wrote: > That will still have a duplicate call as scsi_target_block() has been called already (cf scsi_target_block() in line 539 right at the start of srp_reconnect_rport()). > > (And I don't think we need the WARN_ON_ONCE() here; we are checking for rport->state == SRP_RPORT_BLOCKED just before that line...) How about the patch below? The approach implemented by that patch is only to call scsi_target_block() after a successful transition to the SRP_RPORT_BLOCKED state and to only call scsi_target_unblock() when leaving the SRP_RPORT_BLOCKED state. Thanks, Bart. diff --git a/drivers/scsi/scsi_transport_srp.c b/drivers/scsi/scsi_transport_srp.c index d4d1104fac99..0334f86f0879 100644 --- a/drivers/scsi/scsi_transport_srp.c +++ b/drivers/scsi/scsi_transport_srp.c @@ -402,13 +402,9 @@ static void __rport_fail_io_fast(struct srp_rport *rport) lockdep_assert_held(&rport->mutex); + WARN_ON_ONCE(rport->state != SRP_RPORT_BLOCKED); if (srp_rport_set_state(rport, SRP_RPORT_FAIL_FAST)) return; - /* - * Call scsi_target_block() to wait for ongoing shost->queuecommand() - * calls before invoking i->f->terminate_rport_io(). - */ - scsi_target_block(rport->dev.parent); scsi_target_unblock(rport->dev.parent, SDEV_TRANSPORT_OFFLINE); /* Involve the LLD if possible to terminate all I/O on the rport. */ @@ -541,7 +537,8 @@ int srp_reconnect_rport(struct srp_rport *rport) res = mutex_lock_interruptible(&rport->mutex); if (res) goto out; - scsi_target_block(&shost->shost_gendev); + if (srp_rport_set_state(rport, SRP_RPORT_BLOCKED) == 0) + scsi_target_block(&shost->shost_gendev); res = rport->state != SRP_RPORT_LOST ? i->f->reconnect(rport) : -ENODEV; pr_debug("%s (state %d): transport.reconnect() returned %d\n", dev_name(&shost->shost_gendev), rport->state, res); @@ -569,9 +566,9 @@ int srp_reconnect_rport(struct srp_rport *rport) * and dev_loss off. Mark the port as failed and start the TL * failure timers if these had not yet been started. */ + WARN_ON_ONCE(srp_rport_set_state(rport, SRP_RPORT_BLOCKED)); + scsi_target_block(rport->dev.parent); __rport_fail_io_fast(rport); - scsi_target_unblock(&shost->shost_gendev, - SDEV_TRANSPORT_OFFLINE); __srp_start_tl_fail_timers(rport); } else if (rport->state != SRP_RPORT_BLOCKED) { scsi_target_unblock(&shost->shost_gendev,