Hello, Bart. On Wed, Nov 28, 2012 at 01:51:13PM +0100, Bart Van Assche wrote: > SCSI LLDs may start cleaning up host resources needed by their > queuecommand() callback as soon as scsi_remove_host() finished. > Hence scsi_remove_host() must wait until blk_cleanup_queue() for > all devices associated with the host has finished. That avoids > that queuecommand() gets invoked after scsi_remove_host() > finished. Also, avoid adding new SCSI devices after > scsi_remove_host() started. > > Signed-off-by: Bart Van Assche <bvanassche@xxxxxxx> > Cc: Tejun Heo <tj@xxxxxxxxxx> > Cc: James Bottomley <JBottomley@xxxxxxxxxxxxx> > Cc: Mike Christie <michaelc@xxxxxxxxxxx> > Cc: Hannes Reinecke <hare@xxxxxxx> > --- > drivers/scsi/hosts.c | 30 ++++++++++++++++++++++++++++++ > drivers/scsi/scsi_priv.h | 1 + > drivers/scsi/scsi_sysfs.c | 1 + > include/scsi/scsi_host.h | 1 + > 4 files changed, 33 insertions(+) > > diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c > index 6ae16cd..7bd944e 100644 > --- a/drivers/scsi/hosts.c > +++ b/drivers/scsi/hosts.c > @@ -150,12 +150,31 @@ int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state) > } > EXPORT_SYMBOL(scsi_host_set_state); > > +/* Return true if and only if scsi_remove_host() is allowed to finish. */ > +static bool __scsi_remove_host_done(struct Scsi_Host *shost) > +{ > + lockdep_assert_held(shost->host_lock); > + > + return list_empty(&shost->__devices); > +} This is a preference thing but I usually find this type of trivial wrappers more obfuscating than actually helpful. Dunno what James's preference is tho. > +/* Test whether scsi_remove_host() may finish, and if so, wake it up. */ > +void __scsi_check_remove_host_done(struct Scsi_Host *shost) > +{ > + lockdep_assert_held(shost->host_lock); > + > + if (__scsi_remove_host_done(shost)) > + wake_up(&shost->remove_host); > +} Why the __ prefix? It's not like they have different external/internal versions. This being an one-time thing. Using completion could be simpler. e.g. scsi_check_no_device_left() { if (list_empty(__devices)) complete(host->no_device_left); } scsi_remove_host() { blah blah; scsi_check_remove_host_done(); wait_for_completion(&host->no_device_left); blah blah; } Thanks. -- tejun -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html