summaryrefslogtreecommitdiff
path: root/drivers/scsi/isci/port.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2011-06-13 17:39:44 -0700
committerDan Williams <dan.j.williams@intel.com>2011-07-03 04:04:51 -0700
commit209fae14fabfd48525e5630bebbbd4ca15090c60 (patch)
treeb251b9b394b3493cc15242ea31002abcb4e9bb59 /drivers/scsi/isci/port.c
parent360b03ed178a4fe3971b0a098d8feeb53333481b (diff)
downloadlwn-209fae14fabfd48525e5630bebbbd4ca15090c60.tar.gz
lwn-209fae14fabfd48525e5630bebbbd4ca15090c60.zip
isci: atomic device lookup and reference counting
We have unsafe references to remote devices that are notified to disappear at lldd_dev_gone. In order to clean this up we need a single canonical source for device lookups and stable references once a lookup succeeds. Towards that end guarantee that domain_device.lldd_dev is NULL as soon as we start the process of stopping a device. Any code path that wants to safely lookup a remote device must do so through task->dev->lldd_dev (isci_lookup_device()). For in-flight references outside of scic_lock we need reference counting to ensure that the device is not recycled before we are done with it. Simplify device back references to just scic_sds_request.target_device which is now the only permissible internal reference that is maintained relative to the reference count. There were two occasions where we wanted new i/o's to be treated as SAS_TASK_UNDELIVERED but where the domain_dev->lldd_dev link is still intact. Introduce a 'gone' flag to prevent i/o while waiting for libsas to take action on the port down event. One 'core' leftover is that we currently call scic_remote_device_destruct() from isci_remote_device_deconstruct() which is called when the 'core' says the device is stopped. It would be more natural for the final put to trigger isci_remote_device_deconstruct() but this implementation is deferred as it requires other changes. Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/scsi/isci/port.c')
-rw-r--r--drivers/scsi/isci/port.c3
1 files changed, 1 insertions, 2 deletions
diff --git a/drivers/scsi/isci/port.c b/drivers/scsi/isci/port.c
index fb66e30da075..5f4a4e3954db 100644
--- a/drivers/scsi/isci/port.c
+++ b/drivers/scsi/isci/port.c
@@ -321,8 +321,7 @@ static void isci_port_link_down(struct isci_host *isci_host,
dev_dbg(&isci_host->pdev->dev,
"%s: isci_device = %p\n",
__func__, isci_device);
- isci_remote_device_change_state(isci_device,
- isci_stopping);
+ set_bit(IDEV_GONE, &isci_device->flags);
}
}
isci_port_change_state(isci_port, isci_stopping);