diff options
author | Dan Williams <dan.j.williams@intel.com> | 2011-11-18 02:59:51 +0100 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-02-19 20:52:34 +0100 |
commit | 87c8331fcf72e501c3a3c0cdc5c9391ec72f7cf2 (patch) | |
tree | 4ed0e98760c977010fe54778c1a25625840b4583 /drivers/scsi/libsas/sas_internal.h | |
parent | [SCSI] libsas: convert dev->gone to flags (diff) | |
download | linux-87c8331fcf72e501c3a3c0cdc5c9391ec72f7cf2.tar.xz linux-87c8331fcf72e501c3a3c0cdc5c9391ec72f7cf2.zip |
[SCSI] libsas: prevent domain rediscovery competing with ata error handling
libata error handling provides for a timeout for link recovery. libsas
must not rescan for previously known devices in this interval otherwise
it may remove a device that is simply waiting for its link to recover.
Let libata-eh make the determination of when the link is stable and
prevent libsas (host workqueue) from taking action while this
determination is pending.
Using a mutex (ha->disco_mutex) to flush and disable revalidation while
eh is running requires any discovery action that may block on eh be
moved to its own context outside the lock. Probing ATA devices
explicitly waits on ata-eh and the cache-flush-io issued during device
removal may also pend awaiting eh completion. Essentially any rphy
add/remove activity needs to run outside the lock.
This adds two new cleanup states for sas_unregister_domain_devices()
'allocated-but-not-probed', and 'flagged-for-destruction'. In the
'allocated-but-not-probed' state dev->rphy points to a rphy that is
known to have not been through a sas_rphy_add() event. At domain
teardown check if this device is still pending probe and cleanup
accordingly. Similarly if a device has already been queued for removal
then sas_unregister_domain_devices has nothing to do.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/libsas/sas_internal.h')
-rw-r--r-- | drivers/scsi/libsas/sas_internal.h | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h index 948ea64cc2eb..ebe9b81ddef5 100644 --- a/drivers/scsi/libsas/sas_internal.h +++ b/drivers/scsi/libsas/sas_internal.h @@ -56,6 +56,8 @@ enum blk_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *); int sas_init_queue(struct sas_ha_struct *sas_ha); int sas_init_events(struct sas_ha_struct *sas_ha); void sas_shutdown_queue(struct sas_ha_struct *sas_ha); +void sas_disable_revalidation(struct sas_ha_struct *ha); +void sas_enable_revalidation(struct sas_ha_struct *ha); void sas_deform_port(struct asd_sas_phy *phy, int gone); @@ -138,6 +140,7 @@ static inline struct domain_device *sas_alloc_device(void) if (dev) { INIT_LIST_HEAD(&dev->siblings); INIT_LIST_HEAD(&dev->dev_list_node); + INIT_LIST_HEAD(&dev->disco_list_node); kref_init(&dev->kref); } return dev; |