Re: Silicon Image 3112A SATA trouble

Jens Axboe
2003-11-30T16:51:59Z

On Sun, Nov 30 2003, Jeff Garzik wrote:
> Jens Axboe wrote:
> >On Sun, Nov 30 2003, Bartlomiej Zolnierkiewicz wrote:
> >>Hmm. actually I was under influence that we have generic ioctls in 2.6.x,
> >>but I can find only BLKSECTGET, BLKSECTSET was somehow lost. Jens?
> >
> >
> >Probably because it's very dangerous to expose, echo something too big
> >and watch your data disappear.
>
>
> IMO, agreed.
>
> Max KB per request really should be set by the driver, as it's a
> hardware-specific thing that (as we see :)) is often errata-dependent.

Yes, it would be better to have a per-drive (or hwif) extra limiting
factor if it is needed. For this case it really isn't, so probably not
the best idea :)

> Tangent: My non-pessimistic fix will involve submitting a single sector
> DMA r/w taskfile manually, then proceeding with the remaining sectors in
> another r/w taskfile. This doubles the interrupts on the affected
> chipset/drive combos, but still allows large requests. I'm not terribly

Or split the request 50/50.

> fond of partial completions, as I feel they add complexity, particularly
> so in my case: I can simply use the same error paths for both the
> single-sector taskfile and the "everything else" taskfile, regardless of
> which taskfile throws the error.

It's just a questions of maintaining the proper request state so you
know how much and what part of a request is pending. Requests have been
handled this way ever since clustered requests, that is why
current_nr_sectors differs from nr_sectors. And with hard_* duplicates,
it's pretty easy to extend this a bit. I don't see this as something
complex, and if the alternative you are suggesting (your implementation
idea is not clear to me...) is to fork another request then I think it's
a lot better.

Say you receive a request that violates the magic sector count rule. You
decide to do the first half of the request, and setup your taskfile for
that. You can diminish nr_sectors appropriately, or you can keep this
sector count in the associated taskfile - whatever you prefer. The
end_io path that covers both "normal" and partial IO is basically:

if (!end_that_request_first(rq, 1, sectors))
rq is done
else
rq state is now correctly the 2nd half

In the not-done case, you simply fall out of your isr as you would a
complete request, and let your request_fn just start it again. You don't
even know this request has already been processed.

Depending on whether you remove the request from the queue or not, you
just push the request to the top of the request queue so you are certain
that you start this one next.

So there's really nothing special about partial completions, rather full
completions are a one-shot partial completion :)

> (thinking out loud) Though best for simplicity, I am curious if a
> succession of "tiny/huge" transaction pairs are efficient? I am hoping
> that the drive's cache, coupled with the fact that each pair of
> taskfiles is sequentially contiguous, will not hurt speed too much over
> a non-errata configuration...

My gut would say rather two 64kb than a 124 and 4kb. But you should do
the numbers, of course :). I'd be surprised if the former wouldn't be
more efficient.

--
Jens Axboe