Re: ll_rw_blk.c fails to merge requests. Help!

From: Neil Brown (neilb@cse.unsw.edu.au)
Date: Thu Aug 24 2000 - 00:35:52 EST


On August 23, torvalds@transmeta.com wrote:
> In article <14756.25889.655254.332719@notabene.cse.unsw.edu.au>,
> Neil Brown <neilb@cse.unsw.edu.au> wrote:
> >
> >Not necessarily. When a request is freed, the oldest waiting thread
> >is woken, but it might not actually get to run before some other
> >thread steals the request. You could force a strict ordering if you
> >really wanted to, but I don't know how much it would help. See
> >STRICT_REQUEST_ORDERING in the patch below.
>
> Neil, I suspect the request ordering is secondary, and the real problem
> is that at some point we get into this awful steady state where we
> create new requests at the same pace as we get rid of old ones, and we
> always end up waiting for the next request to be free'd.

I agree. I only commented becuase the orginal question asked about
this and I thought "couldn't hurt to try and see if it makes a
difference.

What I think the "real issue" is (and was addressed by the rest of the
patch but possibly wasn't presented very clearly) is the following:

1/ request for block A arrives. We have no spare requests so we
   sleep.
2/ request for block B arrives (B continguous with A). We have no
   spare requests so we sleep.
3/ something completes, first thread is woken up and it uses the
   request.
4/ something else completes, second thread is woken up. Now it's
   request for block B could be merged with the request for block A,
   but it doesn't bother, it just adds a new request.

This seemed to be what was happening the the trace given.
If two threads, say kupdate and kflushd are both running
flush_dirty_buffers, and the buffers are in device-sequential order,
then we would have them alternately writing sequential blocks.
One the request queue was full, each would block waiting for a
request, and then fail to merge with the request that was just
scheduled by the other.
Net result - lots of small write requests on the queue that could be
merged but aren't.

Hence the code in my patch that went back and tried again to merge
requests after waiting for a request structure.

>
> The normal elevator thing obviously tries to merge first, so truly
> contiguous entries should get merged regardless of whether there are any
> free requests or not. However, we should try to get the "not quite
> contiguous" case right too. And I'm not convinced my theory above is
> valid, but I can see that there could indeed be some bad behaviour
> patterns if we only have one request free at any particular time..

I think that providing every opportunity to merge requests is taken
(see above), there shouldn't be any problems with "only one free
request" situations. The queue is (should be) sufficiently long to
decouple handling of requests off the front from adding new requests to
the end. A bunch of read requests should all have a chance of getting
onto the queue and being merged where appropriate before any of them
get processed. If not, then MAX_READAHEAD is too large, or
QUEUE_NR_REQUESTS is too small (or we need to get the READA command
down to ll_rw_block from generic_file_readahead).

NeilBrown
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Thu Aug 31 2000 - 21:00:12 EST