Re: Silicon Image 3112A SATA trouble
From: Jeff Garzik
Date: Sun Nov 30 2003 - 15:37:22 EST
Jens Axboe wrote:
On Sun, Nov 30 2003, Jeff Garzik wrote:
Since the hardware request API is (and must be) completely decoupled
from struct request API, I can achieve 1.5 x non-errata case.
Hmm I don't follow that... Being a bit clever, you could even send off
both A and B parts of the request in one go. Probably not worth it
though, that would add some complexity (things like not spanning a page,
stuff you probably don't want to bother the driver with).
[...]
Indeed. The partial completions only exist at the driver -> block layer
(or -> scsi) layer, not talking to the hardware. The hardware always
gets 'a request', if that just happens to be only a part of a struct
request so be it.
[...]
Sure yes, the fewer completions the better. Where do you get the 1.5
from? You need to split the request handling no matter what for the
errata path, I would count that as 2 completions.
Taskfile completion and struct request completion are separate. That
results in
* struct request received by libata
* libata detects errata
* libata creates 2 struct ata_queued_cmd's
* libata calls ata_qc_push() 2 times
* Time passes
* ata_qc_complete called 2 times
Option 1: {scsi|block} complete called 2 times, once for each taskfile
Option 2: {scsi|block} complete called 1 time, when both taskfiles are done
one way: 2 h/w completions, 1 struct request completion == 1.5
another way: 2 h/w completions, 2 struct request completions == 2.0
Maybe another way of looking at it:
It's a question of where the state is stored -- in ata_queued_cmd or
entirely in struct request -- and what are the benefits/downsides of each.
When a single struct request causes the initiation of multiple
ata_queued_cmd's, libata must be capable of knowing when multiple
ata_queued_cmds forming a whole have completed. struct request must
also know this. _But_. The key distinction is that libata must handle
multiple requests might not be based on sector progress.
For this SII errata, I _could_ do this at the block layer:
ata_qc_complete() -> blk_end_io(first half of sectors)
ata_qc_complete() -> blk_end_io(some more sectors)
And the request would be completed by the block layer (right?).
But under the hood, libata has to handle these situations:
* One or more ATA commands must complete in succession, before the
struct request may be end_io'd.
* One or more ATA commands must complete asynchronously, before the
struct request may be end_io'd.
* These ATA commands might not be sector based: sometimes aggressive
power management means that libata must issue and complete a PM-related
taskfile, before issuing the {READ|WRITE} DMA passed to it in the struct
request.
I'm already storing and handling this stuff at the hardware-queue level.
(remember hardware queues often bottleneck at the host and/or bus
levels, not necessarily the request_queue level)
So what all this hopefully boils down to is: if I have to do "internal
completions" anyway, it's just more work for libata to separate out the
2 taskfiles into 2 block layer completions. For both errata and
non-errata paths, I can just say "the last taskfile is done, clean up"
Yet another way of looking at it:
In order for all state to be kept at the block layer level, you would
need this check:
if ((rq->expected_taskfiles == rq->completed_taskfiles) &&
(rq->expected_sectors == rq->completed_sectors))
the struct request is "complete"
and each call to end_io would require both a taskfile count and a sector
count, which would increment ->completed_taskfiles and ->completed_sectors.
Note1: s/taskfile/cdb/ if that's your fancy :)
Note2: ->completed_sectors exists today under another name, yes, I know :)
Jeff
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/