Skip to content

Commit 14aaa9f

Browse files
Jeff Skirvindjbw
Jeff Skirvin
authored andcommitted
isci: Redesign device suspension, abort, cleanup.
This commit changes the means by which outstanding I/Os are handled for cleanup. The likelihood is that this commit will be broken into smaller pieces, however that will be a later revision. Among the changes: - All completion structures have been removed from the tmf and abort paths. - Now using one completed I/O list, with the I/O completed in host bit being used to select error or normal callback paths. Signed-off-by: Jeff Skirvin <[email protected]> Signed-off-by: Dan Williams <[email protected]>
1 parent d80ecd5 commit 14aaa9f

11 files changed

+418
-1474
lines changed

drivers/scsi/isci/host.c

+26-60
Original file line numberDiff line numberDiff line change
@@ -1089,102 +1089,63 @@ void isci_host_completion_routine(unsigned long data)
10891089
{
10901090
struct isci_host *ihost = (struct isci_host *)data;
10911091
struct list_head completed_request_list;
1092-
struct list_head errored_request_list;
10931092
struct list_head *current_position;
10941093
struct list_head *next_position;
10951094
struct isci_request *request;
1096-
struct isci_request *next_request;
10971095
struct sas_task *task;
10981096
u16 active;
10991097

11001098
INIT_LIST_HEAD(&completed_request_list);
1101-
INIT_LIST_HEAD(&errored_request_list);
11021099

11031100
spin_lock_irq(&ihost->scic_lock);
11041101

11051102
sci_controller_completion_handler(ihost);
11061103

11071104
/* Take the lists of completed I/Os from the host. */
1108-
11091105
list_splice_init(&ihost->requests_to_complete,
11101106
&completed_request_list);
11111107

1112-
/* Take the list of errored I/Os from the host. */
1113-
list_splice_init(&ihost->requests_to_errorback,
1114-
&errored_request_list);
1115-
11161108
spin_unlock_irq(&ihost->scic_lock);
11171109

1118-
/* Process any completions in the lists. */
1110+
/* Process any completions in the list. */
11191111
list_for_each_safe(current_position, next_position,
11201112
&completed_request_list) {
11211113

11221114
request = list_entry(current_position, struct isci_request,
11231115
completed_node);
11241116
task = isci_request_access_task(request);
11251117

1126-
/* Normal notification (task_done) */
1127-
dev_dbg(&ihost->pdev->dev,
1128-
"%s: Normal - request/task = %p/%p\n",
1129-
__func__,
1130-
request,
1131-
task);
11321118

11331119
/* Return the task to libsas */
11341120
if (task != NULL) {
11351121

11361122
task->lldd_task = NULL;
1137-
if (!(task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
1138-
1139-
/* If the task is already in the abort path,
1140-
* the task_done callback cannot be called.
1141-
*/
1142-
task->task_done(task);
1123+
if (!test_bit(IREQ_ABORT_PATH_ACTIVE, &request->flags) &&
1124+
!(task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
1125+
if (test_bit(IREQ_COMPLETE_IN_TARGET,
1126+
&request->flags)) {
1127+
1128+
/* Normal notification (task_done) */
1129+
dev_dbg(&ihost->pdev->dev, "%s: Normal"
1130+
" - request/task = %p/%p\n",
1131+
__func__, request, task);
1132+
1133+
task->task_done(task);
1134+
} else {
1135+
dev_warn(&ihost->pdev->dev,
1136+
"%s: Error - request/task"
1137+
" = %p/%p\n",
1138+
__func__, request, task);
1139+
1140+
sas_task_abort(task);
1141+
}
11431142
}
11441143
}
11451144

11461145
spin_lock_irq(&ihost->scic_lock);
11471146
isci_free_tag(ihost, request->io_tag);
11481147
spin_unlock_irq(&ihost->scic_lock);
11491148
}
1150-
list_for_each_entry_safe(request, next_request, &errored_request_list,
1151-
completed_node) {
1152-
1153-
task = isci_request_access_task(request);
1154-
1155-
/* Use sas_task_abort */
1156-
dev_warn(&ihost->pdev->dev,
1157-
"%s: Error - request/task = %p/%p\n",
1158-
__func__,
1159-
request,
1160-
task);
1161-
1162-
if (task != NULL) {
1163-
1164-
/* Put the task into the abort path if it's not there
1165-
* already.
1166-
*/
1167-
if (!(task->task_state_flags & SAS_TASK_STATE_ABORTED))
1168-
sas_task_abort(task);
1169-
1170-
} else {
1171-
/* This is a case where the request has completed with a
1172-
* status such that it needed further target servicing,
1173-
* but the sas_task reference has already been removed
1174-
* from the request. Since it was errored, it was not
1175-
* being aborted, so there is nothing to do except free
1176-
* it.
1177-
*/
1178-
1179-
spin_lock_irq(&ihost->scic_lock);
1180-
/* Remove the request from the remote device's list
1181-
* of pending requests.
1182-
*/
1183-
list_del_init(&request->dev_node);
1184-
isci_free_tag(ihost, request->io_tag);
1185-
spin_unlock_irq(&ihost->scic_lock);
1186-
}
1187-
}
11881149

11891150
/* the coalesence timeout doubles at each encoding step, so
11901151
* update it based on the ilog2 value of the outstanding requests
@@ -2345,7 +2306,6 @@ static int sci_controller_dma_alloc(struct isci_host *ihost)
23452306

23462307
ireq->tc = &ihost->task_context_table[i];
23472308
ireq->owning_controller = ihost;
2348-
spin_lock_init(&ireq->state_lock);
23492309
ireq->request_daddr = dma;
23502310
ireq->isci_host = ihost;
23512311
ihost->reqs[i] = ireq;
@@ -2697,6 +2657,10 @@ enum sci_status sci_controller_terminate_request(struct isci_host *ihost,
26972657
return SCI_FAILURE_INVALID_STATE;
26982658
}
26992659
status = sci_io_request_terminate(ireq);
2660+
2661+
dev_dbg(&ihost->pdev->dev, "%s: status=%d; ireq=%p; flags=%lx\n",
2662+
__func__, status, ireq, ireq->flags);
2663+
27002664
if ((status == SCI_SUCCESS) &&
27012665
!test_bit(IREQ_PENDING_ABORT, &ireq->flags) &&
27022666
!test_and_set_bit(IREQ_TC_ABORT_POSTED, &ireq->flags)) {
@@ -2739,6 +2703,8 @@ enum sci_status sci_controller_complete_io(struct isci_host *ihost,
27392703

27402704
index = ISCI_TAG_TCI(ireq->io_tag);
27412705
clear_bit(IREQ_ACTIVE, &ireq->flags);
2706+
if (test_bit(IREQ_ABORT_PATH_ACTIVE, &ireq->flags))
2707+
wake_up_all(&ihost->eventq);
27422708
return SCI_SUCCESS;
27432709
default:
27442710
dev_warn(&ihost->pdev->dev, "%s invalid state: %d\n",

drivers/scsi/isci/host.h

-1
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,6 @@ struct isci_host {
205205
wait_queue_head_t eventq;
206206
struct tasklet_struct completion_tasklet;
207207
struct list_head requests_to_complete;
208-
struct list_head requests_to_errorback;
209208
spinlock_t scic_lock;
210209
struct isci_request *reqs[SCI_MAX_IO_REQUESTS];
211210
struct isci_remote_device devices[SCI_MAX_REMOTE_DEVICES];

drivers/scsi/isci/init.c

-1
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,6 @@ static struct isci_host *isci_host_alloc(struct pci_dev *pdev, int id)
556556
}
557557

558558
INIT_LIST_HEAD(&ihost->requests_to_complete);
559-
INIT_LIST_HEAD(&ihost->requests_to_errorback);
560559
for (i = 0; i < SCI_MAX_PORTS; i++) {
561560
struct isci_port *iport = &ihost->ports[i];
562561

0 commit comments

Comments
 (0)