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 <[email protected]>
> Cc: Tejun Heo <[email protected]>
> Cc: James Bottomley <[email protected]>
> Cc: Mike Christie <[email protected]>
> Cc: Hannes Reinecke <[email protected]>
> ---
> 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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html