Re: floppy driver 2.6.3 question

From: Jens Axboe
Date: Thu Mar 18 2004 - 04:11:39 EST


On Thu, Mar 18 2004, Peter T. Breuer wrote:
> "Also sprach Jens Axboe:"
> > On Wed, Mar 17 2004, Peter T. Breuer wrote:
> > >
> > > In the 2.6.3 floppy driver, when the driver is asked to revalidate by
> > > kernel check_disk_change (after the latter asks and the floppy signalled
> > > media_changed), the floppy driver constructs a read bio for the first
> > > block and submits it via submit_bio, and waits for completion of the
> > > bio.
> > >
> > > However, the bio's embedded completion only signals back if the
> > > submitted bio was successful, as far as I can tell:
> > >
> > >
> > > static int floppy_rb0_complete(struct bio *bio, unsigned int bytes_done, int err)
> > > {
> > > if (bio->bi_size)
> > > return 1;
> > >
> > > complete((struct completion*)bio->bi_private);
> > > return 0;
> > > }
> > >
> > > Note that if the bi_size is nonzero, we return without signalling. Now
> > > bi_size starts out nozero
> > >
> > > bio.bi_size = size;
> > >
> > > but I _think_ bi_size is zeroed along the way somewhere in end_request
> > > (who knows?) if all goes well, so that nonzero means we still have more
> > > to do in this bio. So if things go badly, completion is never signalled
> > > and the submitted read is waited for forever? (and the result is never
> > > tested).
> >
> > You are completely missing how it works... ->bi_end_io() is invoked on
> > every io completion event that the hardware generates,
>
> You are saying the floppy_rb0_complete is possibly called multiple times
> (presumably by end_that_request_first, or whatever_it_is_called :)? I

It is called from end_that_request_first -> bio_endio() -> bi_end_io().
So _if_ the floppy driver uses partial completions (ie several calls to
end_that_request_first(), not just one at the end), then
floppy_rb0_complete will be called multiple times.

> was not aware of that, but it makes sense, thank you. Once for each bio
> in the request. But how can it be called multiple times for each bio?

A bio can contain any amount of data, basically. So if you get hardware
completions for each 512b sector and the bio contains 128K, you'd get
256 completions.

> I'm trying to understand the 2.6 block driver mechanisms :-(.
>
> It's hard btw to see from the code precisely what the args to the call
> of bi_end_io in end_that_request_first are. err seems to be either 0 or
> -EIO (if the whole request was not uptodate) and bytes_done appears
> always to be bi_size for the current bio. __make_request seems to be
> able to generate a WOULDBLOCK error and bytes_done equal to the whole
> request size. Yep - I'm confusicated as to whether there is some
> invariant like bytes_done+bio->bi_size = const or not.

I don't quite follow your last bytes_done+bio->bi_size, that doesn't
make any sense. If __make_request() calls bio_endio() with the full
size, you get floppy_rb0_complete() invoked immediately with bi_size ==
0, ie it completely ends the bio.

> > but typically
> > most only care about the final completion (and not any eventual partial
> > completions along the way).
>
> OK. Where approximately are the partial completion calls generated?

They are generated by the driver.

> > So driver calls end_request* which does a bio_endio() on the number of
> > sectors passed in, which in turn decrements bio->bi_size.
>
> You know, I didn't see any such decrement in end_that-request_first.

Follow the trace on step to bio_endio()

> > _If_
> > bio->bi_size never hits zero, then you have a driver bug. If things 'go
> > badly', then the driver will signal unsuccessful completion of X
> > sectors.
>
> Hmm, presumably in the case of unsuccessful completion, we still get
> bio->b_size == 0 in the call to floppy_rb0_complete? That's good.
> Then we will always be signalled.

Of course we do, otherwise you'd never be able to sleep on io
completion.

> > > submit_bio(READ, &bio);
> > > generic_unplug_device(bdev_get_queue(bdev));
> > > process_fd_request();
> > > wait_for_completion(&complete);
> > >
> > > __free_page(page);
> > >
> > > My reading therefore is that we cannot do revalidation until we are
> > > sure that the floppy is there. If we feel sure, but are wrong, the
> > > test read of the first block will hang during the revalidation.
> >
> > Wrong.
>
> OK, you are saying that the complete will be signalled after the
> request has been errored. Thank you very much for the explanation!

Yes

--
Jens Axboe

-
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/