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>
This commit is contained in:
@@ -213,18 +213,15 @@ int isci_bus_reset_handler(struct scsi_cmnd *cmd);
|
||||
|
||||
void isci_task_build_tmf(
|
||||
struct isci_tmf *tmf,
|
||||
struct isci_remote_device *isci_device,
|
||||
enum isci_tmf_function_codes code,
|
||||
void (*tmf_sent_cb)(enum isci_tmf_cb_state,
|
||||
struct isci_tmf *,
|
||||
void *),
|
||||
void *cb_data);
|
||||
|
||||
|
||||
int isci_task_execute_tmf(
|
||||
struct isci_host *isci_host,
|
||||
struct isci_tmf *tmf,
|
||||
unsigned long timeout_ms);
|
||||
int isci_task_execute_tmf(struct isci_host *isci_host,
|
||||
struct isci_remote_device *idev,
|
||||
struct isci_tmf *tmf, unsigned long timeout_ms);
|
||||
|
||||
/**
|
||||
* enum isci_completion_selection - This enum defines the possible actions to
|
||||
|
Reference in New Issue
Block a user