From: Jens Axboe <axboe@suse.de>
To: "Peter T. Breuer" <ptb@it.uc3m.es>
Cc: linux kernel <linux-kernel@vger.kernel.org>
Subject: Re: floppy driver 2.6.3 question
Date: Thu, 18 Mar 2004 10:10:00 +0100 [thread overview]
Message-ID: <20040318091000.GA22234@suse.de> (raw)
In-Reply-To: <200403180823.i2I8NZs21184@oboe.it.uc3m.es>
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
next prev parent reply other threads:[~2004-03-18 9:10 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-03-17 20:02 floppy driver 2.6.3 question Peter T. Breuer
2004-03-18 7:14 ` Jens Axboe
2004-03-18 8:23 ` Peter T. Breuer
2004-03-18 9:10 ` Jens Axboe [this message]
2004-03-18 10:05 ` Peter T. Breuer
2004-03-18 11:35 ` Jens Axboe
2004-03-18 12:23 ` Peter T. Breuer
2004-03-18 12:28 ` Jens Axboe
2004-03-18 13:25 ` Peter T. Breuer
2004-03-18 13:31 ` Jens Axboe
2004-03-18 16:06 ` Peter T. Breuer
2004-03-18 16:16 ` Jens Axboe
2004-03-18 18:11 ` Peter T. Breuer
2004-03-18 19:05 ` Jens Axboe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20040318091000.GA22234@suse.de \
--to=axboe@suse.de \
--cc=linux-kernel@vger.kernel.org \
--cc=ptb@it.uc3m.es \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.