Skip to content

Commit 79855d1

Browse files
author
Christoph Hellwig
committed
libsas: remove task_collector mode
The task_collector mode (or "latency_injector", (C) Dan Willians) is an optional I/O path in libsas that queues up scsi commands instead of directly sending it to the hardware. It generall increases latencies to in the optiomal case slightly reduce mmio traffic to the hardware. Only the obsolete aic94xx driver and the mvsas driver allowed to use it without recompiling the kernel, and most drivers didn't support it at all. Remove the giant blob of code to allow better optimizations for scsi-mq in the future. Signed-off-by: Christoph Hellwig <[email protected]> Reviewed-by: Hannes Reinecke <[email protected]> Acked-by: Dan Williams <[email protected]>
1 parent 309e7cc commit 79855d1

File tree

20 files changed

+97
-556
lines changed

20 files changed

+97
-556
lines changed

Documentation/scsi/libsas.txt

Lines changed: 4 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -226,9 +226,6 @@ static int register_sas_ha(struct my_sas_ha *my_ha)
226226
my_ha->sas_ha.lldd_dev_found = my_dev_found;
227227
my_ha->sas_ha.lldd_dev_gone = my_dev_gone;
228228

229-
my_ha->sas_ha.lldd_max_execute_num = lldd_max_execute_num; (1)
230-
231-
my_ha->sas_ha.lldd_queue_size = ha_can_queue;
232229
my_ha->sas_ha.lldd_execute_task = my_execute_task;
233230

234231
my_ha->sas_ha.lldd_abort_task = my_abort_task;
@@ -247,28 +244,6 @@ static int register_sas_ha(struct my_sas_ha *my_ha)
247244
return sas_register_ha(&my_ha->sas_ha);
248245
}
249246

250-
(1) This is normally a LLDD parameter, something of the
251-
lines of a task collector. What it tells the SAS Layer is
252-
whether the SAS layer should run in Direct Mode (default:
253-
value 0 or 1) or Task Collector Mode (value greater than 1).
254-
255-
In Direct Mode, the SAS Layer calls Execute Task as soon as
256-
it has a command to send to the SDS, _and_ this is a single
257-
command, i.e. not linked.
258-
259-
Some hardware (e.g. aic94xx) has the capability to DMA more
260-
than one task at a time (interrupt) from host memory. Task
261-
Collector Mode is an optional feature for HAs which support
262-
this in their hardware. (Again, it is completely optional
263-
even if your hardware supports it.)
264-
265-
In Task Collector Mode, the SAS Layer would do _natural_
266-
coalescing of tasks and at the appropriate moment it would
267-
call your driver to DMA more than one task in a single HA
268-
interrupt. DMBS may want to use this by insmod/modprobe
269-
setting the lldd_max_execute_num to something greater than
270-
1.
271-
272247
(2) SAS 1.1 does not define I_T Nexus Reset TMF.
273248

274249
Events
@@ -325,71 +300,22 @@ PHYE_SPINUP_HOLD -- SATA is present, COMWAKE not sent.
325300

326301
The Execute Command SCSI RPC:
327302

328-
int (*lldd_execute_task)(struct sas_task *, int num,
329-
unsigned long gfp_flags);
303+
int (*lldd_execute_task)(struct sas_task *, gfp_t gfp_flags);
330304

331-
Used to queue a task to the SAS LLDD. @task is the tasks to
332-
be executed. @num should be the number of tasks being
333-
queued at this function call (they are linked listed via
334-
task::list), @gfp_mask should be the gfp_mask defining the
335-
context of the caller.
305+
Used to queue a task to the SAS LLDD. @task is the task to be executed.
306+
@gfp_mask is the gfp_mask defining the context of the caller.
336307

337308
This function should implement the Execute Command SCSI RPC,
338-
or if you're sending a SCSI Task as linked commands, you
339-
should also use this function.
340309

341-
That is, when lldd_execute_task() is called, the command(s)
310+
That is, when lldd_execute_task() is called, the command
342311
go out on the transport *immediately*. There is *no*
343312
queuing of any sort and at any level in a SAS LLDD.
344313

345-
The use of task::list is two-fold, one for linked commands,
346-
the other discussed below.
347-
348-
It is possible to queue up more than one task at a time, by
349-
initializing the list element of struct sas_task, and
350-
passing the number of tasks enlisted in this manner in num.
351-
352314
Returns: -SAS_QUEUE_FULL, -ENOMEM, nothing was queued;
353315
0, the task(s) were queued.
354316

355-
If you want to pass num > 1, then either
356-
A) you're the only caller of this function and keep track
357-
of what you've queued to the LLDD, or
358-
B) you know what you're doing and have a strategy of
359-
retrying.
360-
361-
As opposed to queuing one task at a time (function call),
362-
batch queuing of tasks, by having num > 1, greatly
363-
simplifies LLDD code, sequencer code, and _hardware design_,
364-
and has some performance advantages in certain situations
365-
(DBMS).
366-
367-
The LLDD advertises if it can take more than one command at
368-
a time at lldd_execute_task(), by setting the
369-
lldd_max_execute_num parameter (controlled by "collector"
370-
module parameter in aic94xx SAS LLDD).
371-
372-
You should leave this to the default 1, unless you know what
373-
you're doing.
374-
375-
This is a function of the LLDD, to which the SAS layer can
376-
cater to.
377-
378-
int lldd_queue_size
379-
The host adapter's queue size. This is the maximum
380-
number of commands the lldd can have pending to domain
381-
devices on behalf of all upper layers submitting through
382-
lldd_execute_task().
383-
384-
You really want to set this to something (much) larger than
385-
1.
386-
387-
This _really_ has absolutely nothing to do with queuing.
388-
There is no queuing in SAS LLDDs.
389-
390317
struct sas_task {
391318
dev -- the device this task is destined to
392-
list -- must be initialized (INIT_LIST_HEAD)
393319
task_proto -- _one_ of enum sas_proto
394320
scatter -- pointer to scatter gather list array
395321
num_scatter -- number of elements in scatter

drivers/scsi/aic94xx/aic94xx.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ void asd_dev_gone(struct domain_device *dev);
7878

7979
void asd_invalidate_edb(struct asd_ascb *ascb, int edb_id);
8080

81-
int asd_execute_task(struct sas_task *, int num, gfp_t gfp_flags);
81+
int asd_execute_task(struct sas_task *task, gfp_t gfp_flags);
8282

8383
void asd_set_dmamode(struct domain_device *dev);
8484

drivers/scsi/aic94xx/aic94xx_hwi.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,8 +1200,7 @@ static void asd_start_scb_timers(struct list_head *list)
12001200
* Case A: we can send the whole batch at once. Increment "pending"
12011201
* in the beginning of this function, when it is checked, in order to
12021202
* eliminate races when this function is called by multiple processes.
1203-
* Case B: should never happen if the managing layer considers
1204-
* lldd_queue_size.
1203+
* Case B: should never happen.
12051204
*/
12061205
int asd_post_ascb_list(struct asd_ha_struct *asd_ha, struct asd_ascb *ascb,
12071206
int num)

drivers/scsi/aic94xx/aic94xx_init.c

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,6 @@ MODULE_PARM_DESC(use_msi, "\n"
4949
"\tEnable(1) or disable(0) using PCI MSI.\n"
5050
"\tDefault: 0");
5151

52-
static int lldd_max_execute_num = 0;
53-
module_param_named(collector, lldd_max_execute_num, int, S_IRUGO);
54-
MODULE_PARM_DESC(collector, "\n"
55-
"\tIf greater than one, tells the SAS Layer to run in Task Collector\n"
56-
"\tMode. If 1 or 0, tells the SAS Layer to run in Direct Mode.\n"
57-
"\tThe aic94xx SAS LLDD supports both modes.\n"
58-
"\tDefault: 0 (Direct Mode).\n");
59-
6052
static struct scsi_transport_template *aic94xx_transport_template;
6153
static int asd_scan_finished(struct Scsi_Host *, unsigned long);
6254
static void asd_scan_start(struct Scsi_Host *);
@@ -711,9 +703,6 @@ static int asd_register_sas_ha(struct asd_ha_struct *asd_ha)
711703
asd_ha->sas_ha.sas_port= sas_ports;
712704
asd_ha->sas_ha.num_phys= ASD_MAX_PHYS;
713705

714-
asd_ha->sas_ha.lldd_queue_size = asd_ha->seq.can_queue;
715-
asd_ha->sas_ha.lldd_max_execute_num = lldd_max_execute_num;
716-
717706
return sas_register_ha(&asd_ha->sas_ha);
718707
}
719708

drivers/scsi/aic94xx/aic94xx_task.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -543,8 +543,7 @@ static int asd_can_queue(struct asd_ha_struct *asd_ha, int num)
543543
return res;
544544
}
545545

546-
int asd_execute_task(struct sas_task *task, const int num,
547-
gfp_t gfp_flags)
546+
int asd_execute_task(struct sas_task *task, gfp_t gfp_flags)
548547
{
549548
int res = 0;
550549
LIST_HEAD(alist);
@@ -553,11 +552,11 @@ int asd_execute_task(struct sas_task *task, const int num,
553552
struct asd_ha_struct *asd_ha = task->dev->port->ha->lldd_ha;
554553
unsigned long flags;
555554

556-
res = asd_can_queue(asd_ha, num);
555+
res = asd_can_queue(asd_ha, 1);
557556
if (res)
558557
return res;
559558

560-
res = num;
559+
res = 1;
561560
ascb = asd_ascb_alloc_list(asd_ha, &res, gfp_flags);
562561
if (res) {
563562
res = -ENOMEM;
@@ -568,7 +567,7 @@ int asd_execute_task(struct sas_task *task, const int num,
568567
list_for_each_entry(a, &alist, list) {
569568
a->uldd_task = t;
570569
t->lldd_task = a;
571-
t = list_entry(t->list.next, struct sas_task, list);
570+
break;
572571
}
573572
list_for_each_entry(a, &alist, list) {
574573
t = a->uldd_task;
@@ -601,7 +600,7 @@ int asd_execute_task(struct sas_task *task, const int num,
601600
}
602601
list_del_init(&alist);
603602

604-
res = asd_post_ascb_list(asd_ha, ascb, num);
603+
res = asd_post_ascb_list(asd_ha, ascb, 1);
605604
if (unlikely(res)) {
606605
a = NULL;
607606
__list_add(&alist, ascb->list.prev, &ascb->list);
@@ -639,6 +638,6 @@ int asd_execute_task(struct sas_task *task, const int num,
639638
out_err:
640639
if (ascb)
641640
asd_ascb_free_list(ascb);
642-
asd_can_dequeue(asd_ha, num);
641+
asd_can_dequeue(asd_ha, 1);
643642
return res;
644643
}

drivers/scsi/isci/init.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,6 @@ static int isci_register_sas_ha(struct isci_host *isci_host)
260260
sas_ha->sas_port = sas_ports;
261261
sas_ha->num_phys = SCI_MAX_PHYS;
262262

263-
sas_ha->lldd_queue_size = ISCI_CAN_QUEUE_VAL;
264-
sas_ha->lldd_max_execute_num = 1;
265263
sas_ha->strict_wide_ports = 1;
266264

267265
sas_register_ha(sas_ha);

drivers/scsi/isci/task.c

Lines changed: 70 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -117,104 +117,97 @@ static inline int isci_device_io_ready(struct isci_remote_device *idev,
117117
* functions. This function is called by libsas to send a task down to
118118
* hardware.
119119
* @task: This parameter specifies the SAS task to send.
120-
* @num: This parameter specifies the number of tasks to queue.
121120
* @gfp_flags: This parameter specifies the context of this call.
122121
*
123122
* status, zero indicates success.
124123
*/
125-
int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags)
124+
int isci_task_execute_task(struct sas_task *task, gfp_t gfp_flags)
126125
{
127126
struct isci_host *ihost = dev_to_ihost(task->dev);
128127
struct isci_remote_device *idev;
129128
unsigned long flags;
129+
enum sci_status status = SCI_FAILURE;
130130
bool io_ready;
131131
u16 tag;
132132

133-
dev_dbg(&ihost->pdev->dev, "%s: num=%d\n", __func__, num);
133+
spin_lock_irqsave(&ihost->scic_lock, flags);
134+
idev = isci_lookup_device(task->dev);
135+
io_ready = isci_device_io_ready(idev, task);
136+
tag = isci_alloc_tag(ihost);
137+
spin_unlock_irqrestore(&ihost->scic_lock, flags);
134138

135-
for_each_sas_task(num, task) {
136-
enum sci_status status = SCI_FAILURE;
139+
dev_dbg(&ihost->pdev->dev,
140+
"task: %p, dev: %p idev: %p:%#lx cmd = %p\n",
141+
task, task->dev, idev, idev ? idev->flags : 0,
142+
task->uldd_task);
137143

138-
spin_lock_irqsave(&ihost->scic_lock, flags);
139-
idev = isci_lookup_device(task->dev);
140-
io_ready = isci_device_io_ready(idev, task);
141-
tag = isci_alloc_tag(ihost);
142-
spin_unlock_irqrestore(&ihost->scic_lock, flags);
144+
if (!idev) {
145+
isci_task_refuse(ihost, task, SAS_TASK_UNDELIVERED,
146+
SAS_DEVICE_UNKNOWN);
147+
} else if (!io_ready || tag == SCI_CONTROLLER_INVALID_IO_TAG) {
148+
/* Indicate QUEUE_FULL so that the scsi midlayer
149+
* retries.
150+
*/
151+
isci_task_refuse(ihost, task, SAS_TASK_COMPLETE,
152+
SAS_QUEUE_FULL);
153+
} else {
154+
/* There is a device and it's ready for I/O. */
155+
spin_lock_irqsave(&task->task_state_lock, flags);
143156

144-
dev_dbg(&ihost->pdev->dev,
145-
"task: %p, num: %d dev: %p idev: %p:%#lx cmd = %p\n",
146-
task, num, task->dev, idev, idev ? idev->flags : 0,
147-
task->uldd_task);
148-
149-
if (!idev) {
150-
isci_task_refuse(ihost, task, SAS_TASK_UNDELIVERED,
151-
SAS_DEVICE_UNKNOWN);
152-
} else if (!io_ready || tag == SCI_CONTROLLER_INVALID_IO_TAG) {
153-
/* Indicate QUEUE_FULL so that the scsi midlayer
154-
* retries.
155-
*/
156-
isci_task_refuse(ihost, task, SAS_TASK_COMPLETE,
157-
SAS_QUEUE_FULL);
157+
if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
158+
/* The I/O was aborted. */
159+
spin_unlock_irqrestore(&task->task_state_lock, flags);
160+
161+
isci_task_refuse(ihost, task,
162+
SAS_TASK_UNDELIVERED,
163+
SAM_STAT_TASK_ABORTED);
158164
} else {
159-
/* There is a device and it's ready for I/O. */
160-
spin_lock_irqsave(&task->task_state_lock, flags);
161-
162-
if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
163-
/* The I/O was aborted. */
164-
spin_unlock_irqrestore(&task->task_state_lock,
165-
flags);
166-
167-
isci_task_refuse(ihost, task,
168-
SAS_TASK_UNDELIVERED,
169-
SAM_STAT_TASK_ABORTED);
170-
} else {
171-
task->task_state_flags |= SAS_TASK_AT_INITIATOR;
165+
task->task_state_flags |= SAS_TASK_AT_INITIATOR;
166+
spin_unlock_irqrestore(&task->task_state_lock, flags);
167+
168+
/* build and send the request. */
169+
status = isci_request_execute(ihost, idev, task, tag);
170+
171+
if (status != SCI_SUCCESS) {
172+
spin_lock_irqsave(&task->task_state_lock, flags);
173+
/* Did not really start this command. */
174+
task->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
172175
spin_unlock_irqrestore(&task->task_state_lock, flags);
173176

174-
/* build and send the request. */
175-
status = isci_request_execute(ihost, idev, task, tag);
176-
177-
if (status != SCI_SUCCESS) {
178-
179-
spin_lock_irqsave(&task->task_state_lock, flags);
180-
/* Did not really start this command. */
181-
task->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
182-
spin_unlock_irqrestore(&task->task_state_lock, flags);
183-
184-
if (test_bit(IDEV_GONE, &idev->flags)) {
185-
186-
/* Indicate that the device
187-
* is gone.
188-
*/
189-
isci_task_refuse(ihost, task,
190-
SAS_TASK_UNDELIVERED,
191-
SAS_DEVICE_UNKNOWN);
192-
} else {
193-
/* Indicate QUEUE_FULL so that
194-
* the scsi midlayer retries.
195-
* If the request failed for
196-
* remote device reasons, it
197-
* gets returned as
198-
* SAS_TASK_UNDELIVERED next
199-
* time through.
200-
*/
201-
isci_task_refuse(ihost, task,
202-
SAS_TASK_COMPLETE,
203-
SAS_QUEUE_FULL);
204-
}
177+
if (test_bit(IDEV_GONE, &idev->flags)) {
178+
/* Indicate that the device
179+
* is gone.
180+
*/
181+
isci_task_refuse(ihost, task,
182+
SAS_TASK_UNDELIVERED,
183+
SAS_DEVICE_UNKNOWN);
184+
} else {
185+
/* Indicate QUEUE_FULL so that
186+
* the scsi midlayer retries.
187+
* If the request failed for
188+
* remote device reasons, it
189+
* gets returned as
190+
* SAS_TASK_UNDELIVERED next
191+
* time through.
192+
*/
193+
isci_task_refuse(ihost, task,
194+
SAS_TASK_COMPLETE,
195+
SAS_QUEUE_FULL);
205196
}
206197
}
207198
}
208-
if (status != SCI_SUCCESS && tag != SCI_CONTROLLER_INVALID_IO_TAG) {
209-
spin_lock_irqsave(&ihost->scic_lock, flags);
210-
/* command never hit the device, so just free
211-
* the tci and skip the sequence increment
212-
*/
213-
isci_tci_free(ihost, ISCI_TAG_TCI(tag));
214-
spin_unlock_irqrestore(&ihost->scic_lock, flags);
215-
}
216-
isci_put_device(idev);
217199
}
200+
201+
if (status != SCI_SUCCESS && tag != SCI_CONTROLLER_INVALID_IO_TAG) {
202+
spin_lock_irqsave(&ihost->scic_lock, flags);
203+
/* command never hit the device, so just free
204+
* the tci and skip the sequence increment
205+
*/
206+
isci_tci_free(ihost, ISCI_TAG_TCI(tag));
207+
spin_unlock_irqrestore(&ihost->scic_lock, flags);
208+
}
209+
210+
isci_put_device(idev);
218211
return 0;
219212
}
220213

0 commit comments

Comments
 (0)