aboutsummaryrefslogtreecommitdiffstats
path: root/include/scsi/libsas.h
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2011-11-17 20:59:51 -0500
committerJames Bottomley <JBottomley@Parallels.com>2012-02-19 14:52:34 -0500
commit87c8331fcf72e501c3a3c0cdc5c9391ec72f7cf2 (patch)
tree4ed0e98760c977010fe54778c1a25625840b4583 /include/scsi/libsas.h
parente139942d77a6e3ac83bc322e826668054a8601d6 (diff)
[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 'include/scsi/libsas.h')
-rw-r--r--include/scsi/libsas.h12
1 files changed, 10 insertions, 2 deletions
diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h
index d792b13cfcf5..bd6e89ece2ab 100644
--- a/include/scsi/libsas.h
+++ b/include/scsi/libsas.h
@@ -86,7 +86,9 @@ enum discover_event {
86 DISCE_DISCOVER_DOMAIN = 0U, 86 DISCE_DISCOVER_DOMAIN = 0U,
87 DISCE_REVALIDATE_DOMAIN = 1, 87 DISCE_REVALIDATE_DOMAIN = 1,
88 DISCE_PORT_GONE = 2, 88 DISCE_PORT_GONE = 2,
89 DISC_NUM_EVENTS = 3, 89 DISCE_PROBE = 3,
90 DISCE_DESTRUCT = 4,
91 DISC_NUM_EVENTS = 5,
90}; 92};
91 93
92/* ---------- Expander Devices ---------- */ 94/* ---------- Expander Devices ---------- */
@@ -175,6 +177,7 @@ struct sata_device {
175 177
176enum { 178enum {
177 SAS_DEV_GONE, 179 SAS_DEV_GONE,
180 SAS_DEV_DESTROY,
178}; 181};
179 182
180struct domain_device { 183struct domain_device {
@@ -191,6 +194,7 @@ struct domain_device {
191 struct asd_sas_port *port; /* shortcut to root of the tree */ 194 struct asd_sas_port *port; /* shortcut to root of the tree */
192 195
193 struct list_head dev_list_node; 196 struct list_head dev_list_node;
197 struct list_head disco_list_node; /* awaiting probe or destruct */
194 198
195 enum sas_protocol iproto; 199 enum sas_protocol iproto;
196 enum sas_protocol tproto; 200 enum sas_protocol tproto;
@@ -226,7 +230,6 @@ struct sas_discovery {
226 int max_level; 230 int max_level;
227}; 231};
228 232
229
230/* The port struct is Class:RW, driver:RO */ 233/* The port struct is Class:RW, driver:RO */
231struct asd_sas_port { 234struct asd_sas_port {
232/* private: */ 235/* private: */
@@ -236,6 +239,8 @@ struct asd_sas_port {
236 struct domain_device *port_dev; 239 struct domain_device *port_dev;
237 spinlock_t dev_list_lock; 240 spinlock_t dev_list_lock;
238 struct list_head dev_list; 241 struct list_head dev_list;
242 struct list_head disco_list;
243 struct list_head destroy_list;
239 enum sas_linkrate linkrate; 244 enum sas_linkrate linkrate;
240 245
241 struct sas_phy *phy; 246 struct sas_phy *phy;
@@ -334,6 +339,7 @@ struct sas_ha_event {
334enum sas_ha_state { 339enum sas_ha_state {
335 SAS_HA_REGISTERED, 340 SAS_HA_REGISTERED,
336 SAS_HA_DRAINING, 341 SAS_HA_DRAINING,
342 SAS_HA_ATA_EH_ACTIVE,
337}; 343};
338 344
339struct sas_ha_struct { 345struct sas_ha_struct {
@@ -346,6 +352,8 @@ struct sas_ha_struct {
346 unsigned long state; 352 unsigned long state;
347 spinlock_t state_lock; 353 spinlock_t state_lock;
348 354
355 struct mutex disco_mutex;
356
349 struct scsi_core core; 357 struct scsi_core core;
350 358
351/* public: */ 359/* public: */