Commit 8acaec15 authored by Dan Williams's avatar Dan Williams

isci: kill "host quiesce" mechanism

The midlayer is already throttling i/o in the places where host_quiesce
was trying to prevent further i/o to the device.  It's also problematic
in that it holds a lock over GFP_KERNEL allocations.
Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent 3a97eec6
...@@ -73,7 +73,6 @@ enum isci_status { ...@@ -73,7 +73,6 @@ enum isci_status {
isci_ready_for_io = 0x03, isci_ready_for_io = 0x03,
isci_stopping = 0x04, isci_stopping = 0x04,
isci_stopped = 0x05, isci_stopped = 0x05,
isci_host_quiesce = 0x06
}; };
/** /**
......
...@@ -267,36 +267,13 @@ isci_remote_device_alloc(struct isci_host *isci_host, struct isci_port *port) ...@@ -267,36 +267,13 @@ isci_remote_device_alloc(struct isci_host *isci_host, struct isci_port *port)
INIT_LIST_HEAD(&isci_device->reqs_in_process); INIT_LIST_HEAD(&isci_device->reqs_in_process);
INIT_LIST_HEAD(&isci_device->node); INIT_LIST_HEAD(&isci_device->node);
isci_device->host_quiesce = false;
spin_lock_init(&isci_device->state_lock); spin_lock_init(&isci_device->state_lock);
spin_lock_init(&isci_device->host_quiesce_lock);
isci_remote_device_change_state(isci_device, isci_freed); isci_remote_device_change_state(isci_device, isci_freed);
return isci_device; return isci_device;
} }
/**
* isci_device_set_host_quiesce_lock_state() - This function sets the host I/O
* quiesce lock state for the remote_device object.
* @isci_device,: This parameter points to the isci_remote_device object
* @isci_device: This parameter specifies the new quiesce state.
*
*/
void isci_device_set_host_quiesce_lock_state(
struct isci_remote_device *isci_device,
bool lock_state)
{
unsigned long flags;
dev_dbg(&isci_device->isci_port->isci_host->pdev->dev,
"%s: isci_device=%p, lock_state=%d\n",
__func__, isci_device, lock_state);
spin_lock_irqsave(&isci_device->host_quiesce_lock, flags);
isci_device->host_quiesce = lock_state;
spin_unlock_irqrestore(&isci_device->host_quiesce_lock, flags);
}
/** /**
* isci_remote_device_ready() - This function is called by the scic when the * isci_remote_device_ready() - This function is called by the scic when the
...@@ -314,8 +291,8 @@ void isci_remote_device_ready(struct isci_remote_device *isci_device) ...@@ -314,8 +291,8 @@ void isci_remote_device_ready(struct isci_remote_device *isci_device)
"%s: isci_device = %p\n", __func__, isci_device); "%s: isci_device = %p\n", __func__, isci_device);
/* device ready is actually a "ready for io" state. */ /* device ready is actually a "ready for io" state. */
if ((isci_starting == isci_remote_device_get_state(isci_device)) || if (isci_device->status == isci_starting ||
(isci_ready == isci_remote_device_get_state(isci_device))) { isci_device->status == isci_ready) {
spin_lock_irqsave(&isci_device->isci_port->remote_device_lock, spin_lock_irqsave(&isci_device->isci_port->remote_device_lock,
flags); flags);
isci_remote_device_change_state(isci_device, isci_ready_for_io); isci_remote_device_change_state(isci_device, isci_ready_for_io);
......
...@@ -68,8 +68,6 @@ struct isci_remote_device { ...@@ -68,8 +68,6 @@ struct isci_remote_device {
struct list_head reqs_in_process; struct list_head reqs_in_process;
struct work_struct stop_work; struct work_struct stop_work;
spinlock_t state_lock; spinlock_t state_lock;
spinlock_t host_quiesce_lock;
bool host_quiesce;
}; };
static inline struct scic_sds_remote_device *to_sci_dev(struct isci_remote_device *idev) static inline struct scic_sds_remote_device *to_sci_dev(struct isci_remote_device *idev)
...@@ -84,22 +82,6 @@ static inline struct scic_sds_remote_device *to_sci_dev(struct isci_remote_devic ...@@ -84,22 +82,6 @@ static inline struct scic_sds_remote_device *to_sci_dev(struct isci_remote_devic
#define ISCI_REMOTE_DEVICE_START_TIMEOUT 5000 #define ISCI_REMOTE_DEVICE_START_TIMEOUT 5000
/**
* This function gets the status of the remote_device object.
* @isci_device: This parameter points to the isci_remote_device object
*
* status of the object as a isci_status enum.
*/
static inline
enum isci_status isci_remote_device_get_state(
struct isci_remote_device *isci_device)
{
return (isci_device->host_quiesce)
? isci_host_quiesce
: isci_device->status;
}
/** /**
* isci_dev_from_domain_dev() - This accessor retrieves the remote_device * isci_dev_from_domain_dev() - This accessor retrieves the remote_device
* object reference from the Linux domain_device reference. * object reference from the Linux domain_device reference.
...@@ -146,10 +128,6 @@ bool isci_device_is_reset_pending( ...@@ -146,10 +128,6 @@ bool isci_device_is_reset_pending(
void isci_device_clear_reset_pending( void isci_device_clear_reset_pending(
struct isci_remote_device *isci_device); struct isci_remote_device *isci_device);
void isci_device_set_host_quiesce_lock_state(
struct isci_remote_device *isci_device,
bool lock_state);
void isci_remote_device_change_state( void isci_remote_device_change_state(
struct isci_remote_device *isci_device, struct isci_remote_device *isci_device,
enum isci_status status); enum isci_status status);
......
...@@ -81,7 +81,6 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags) ...@@ -81,7 +81,6 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags)
struct isci_request *request = NULL; struct isci_request *request = NULL;
struct isci_remote_device *device; struct isci_remote_device *device;
unsigned long flags; unsigned long flags;
unsigned long quiesce_flags = 0;
int ret; int ret;
enum sci_status status; enum sci_status status;
...@@ -151,21 +150,7 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags) ...@@ -151,21 +150,7 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags)
isci_host = isci_host_from_sas_ha(task->dev->port->ha); isci_host = isci_host_from_sas_ha(task->dev->port->ha);
/* check if the controller hasn't started or if the device if (device && device->status == isci_ready) {
* is ready but not accepting IO.
*/
if (device) {
spin_lock_irqsave(&device->host_quiesce_lock,
quiesce_flags);
}
/* From this point onward, any process that needs to guarantee
* that there is no kernel I/O being started will have to wait
* for the quiesce spinlock.
*/
if ((device && ((isci_remote_device_get_state(device) == isci_ready) ||
(isci_remote_device_get_state(device) == isci_host_quiesce)))) {
/* Forces a retry from scsi mid layer. */ /* Forces a retry from scsi mid layer. */
dev_warn(task->dev->port->ha->dev, dev_warn(task->dev->port->ha->dev,
...@@ -179,8 +164,7 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags) ...@@ -179,8 +164,7 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags)
if (device) if (device)
dev_dbg(task->dev->port->ha->dev, dev_dbg(task->dev->port->ha->dev,
"%s: device->status = 0x%x\n", "%s: device->status = 0x%x\n",
__func__, __func__, device->status);
isci_remote_device_get_state(device));
/* Indicate QUEUE_FULL so that the scsi midlayer /* Indicate QUEUE_FULL so that the scsi midlayer
* retries. * retries.
...@@ -194,7 +178,7 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags) ...@@ -194,7 +178,7 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags)
isci_host_can_dequeue(isci_host, 1); isci_host_can_dequeue(isci_host, 1);
} }
/* the device is going down... */ /* the device is going down... */
else if (!device || (isci_ready_for_io != isci_remote_device_get_state(device))) { else if (!device || device->status != isci_ready_for_io) {
dev_dbg(task->dev->port->ha->dev, dev_dbg(task->dev->port->ha->dev,
"%s: task %p: isci_host->status = %d, " "%s: task %p: isci_host->status = %d, "
...@@ -207,8 +191,7 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags) ...@@ -207,8 +191,7 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags)
if (device) if (device)
dev_dbg(task->dev->port->ha->dev, dev_dbg(task->dev->port->ha->dev,
"%s: device->status = 0x%x\n", "%s: device->status = 0x%x\n",
__func__, __func__, device->status);
isci_remote_device_get_state(device));
/* Indicate SAS_TASK_UNDELIVERED, so that the scsi /* Indicate SAS_TASK_UNDELIVERED, so that the scsi
* midlayer removes the target. * midlayer removes the target.
...@@ -247,11 +230,6 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags) ...@@ -247,11 +230,6 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags)
isci_host_can_dequeue(isci_host, 1); isci_host_can_dequeue(isci_host, 1);
} }
} }
if (device) {
spin_unlock_irqrestore(&device->host_quiesce_lock,
quiesce_flags
);
}
task = list_entry(task->list.next, struct sas_task, list); task = list_entry(task->list.next, struct sas_task, list);
} while (--num > 0); } while (--num > 0);
return 0; return 0;
...@@ -442,14 +420,11 @@ int isci_task_execute_tmf( ...@@ -442,14 +420,11 @@ int isci_task_execute_tmf(
/* sanity check, return TMF_RESP_FUNC_FAILED /* sanity check, return TMF_RESP_FUNC_FAILED
* if the device is not there and ready. * if the device is not there and ready.
*/ */
if (!isci_device || if (!isci_device || isci_device->status != isci_ready_for_io) {
((isci_ready_for_io != isci_remote_device_get_state(isci_device)) &&
(isci_host_quiesce != isci_remote_device_get_state(isci_device)))) {
dev_dbg(&isci_host->pdev->dev, dev_dbg(&isci_host->pdev->dev,
"%s: isci_device = %p not ready (%d)\n", "%s: isci_device = %p not ready (%d)\n",
__func__, __func__,
isci_device, isci_device, isci_device->status);
isci_remote_device_get_state(isci_device));
return TMF_RESP_FUNC_FAILED; return TMF_RESP_FUNC_FAILED;
} else } else
dev_dbg(&isci_host->pdev->dev, dev_dbg(&isci_host->pdev->dev,
...@@ -986,9 +961,6 @@ int isci_task_lu_reset( ...@@ -986,9 +961,6 @@ int isci_task_lu_reset(
return TMF_RESP_FUNC_FAILED; return TMF_RESP_FUNC_FAILED;
} }
/* Stop I/O to the remote device. */
isci_device_set_host_quiesce_lock_state(isci_device, true);
/* Send the task management part of the reset. */ /* Send the task management part of the reset. */
if (sas_protocol_ata(domain_device->tproto)) { if (sas_protocol_ata(domain_device->tproto)) {
ret = isci_task_send_lu_reset_sata( ret = isci_task_send_lu_reset_sata(
...@@ -1004,9 +976,6 @@ int isci_task_lu_reset( ...@@ -1004,9 +976,6 @@ int isci_task_lu_reset(
isci_device, isci_device,
terminating); terminating);
/* Resume I/O to the remote device. */
isci_device_set_host_quiesce_lock_state(isci_device, false);
return ret; return ret;
} }
...@@ -1627,9 +1596,6 @@ int isci_bus_reset_handler(struct scsi_cmnd *cmd) ...@@ -1627,9 +1596,6 @@ int isci_bus_reset_handler(struct scsi_cmnd *cmd)
if (isci_host != NULL) if (isci_host != NULL)
spin_unlock_irqrestore(&isci_host->scic_lock, flags); spin_unlock_irqrestore(&isci_host->scic_lock, flags);
/* Stop I/O to the remote device. */
isci_device_set_host_quiesce_lock_state(isci_dev, true);
/* Make sure all pending requests are able to be fully terminated. */ /* Make sure all pending requests are able to be fully terminated. */
isci_device_clear_reset_pending(isci_dev); isci_device_clear_reset_pending(isci_dev);
...@@ -1671,8 +1637,5 @@ int isci_bus_reset_handler(struct scsi_cmnd *cmd) ...@@ -1671,8 +1637,5 @@ int isci_bus_reset_handler(struct scsi_cmnd *cmd)
"%s: cmd %p, isci_dev %p complete.\n", "%s: cmd %p, isci_dev %p complete.\n",
__func__, cmd, isci_dev); __func__, cmd, isci_dev);
/* Resume I/O to the remote device. */
isci_device_set_host_quiesce_lock_state(isci_dev, false);
return TMF_RESP_FUNC_COMPLETE; return TMF_RESP_FUNC_COMPLETE;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment