[please cc: me as not subscribed to list]
I was trying to see how __make_request throttles a fast writing process
from overrunning a slow device. So I took Alessandro Rubini's spull.c
code from his device driver book (2nd edition) and ran it in "pseudo irq"
mode. What the driver does basically is to schedule an alarm in its
request service function (spull_irqdriven_request) and return immediately
without calling end_request. And when the alarm fires it finishes the IO
by calling end_request(1). I made the following change to the driver:
1. make the ram disk size infinite by setting blk_size[MAJOR_NR]=NULL.
2. disable the actual copying to/from the ram disk by commenting out
spull_transfer in the spull_irqdriven_request function.
I load the driver with a 3 second delay for the alarm. So basically, the
driver simulates a "very slow" device that takes 3 seconds to service
each request (without actually doing anything). Now I do:
dd if=/dev/zero of=/dev/pda bs=1024 count=1000000
What I expect is that the kernel will quickly stop dd after all 128 (64
on machines with less than 32MB of ram) free request slots are taken.
Of course it will take forever for dd to finish. But what happened is
that the system quickly becomes unusable. It still handles a request
every 3 seconds but is otherwise oblivious of any input (I can still
switch virtual console but that's it). Is this the expected behavior of
2.4 or am I just doing something stupid? Your insight will be highly
appreciated. Thanks in advance.
--
/Gong
> I was trying to see how __make_request throttles a fast writing process
> from overrunning a slow device. So I took Alessandro Rubini's spull.c
> code from his device driver book (2nd edition)
Alessandro's...and that other guy's...:)
> dd if=/dev/zero of=/dev/pda bs=1024 count=1000000
>
> What I expect is that the kernel will quickly stop dd after all 128 (64
> on machines with less than 32MB of ram) free request slots are taken.
As you noted, that didn't happen. My guess is you ran out of memory. The
requests you are generating will be, shall we say, easily merged in the
block subsystem. So you have a bunch of requests in the device's queue,
but each one will have a long chain of buffer heads hanging off it. You
may not have even managed to use up all the available request structures
before things came to a halt. Try dropping the max_sectors[] count way
down, and things might work a little better. After your fsck completes,
that is.
jon
Jonathan Corbet
Executive editor, LWN.net
[email protected]
Hi Jon, sorry I forgot to mention your name in the post and thank you
very much for the reply. I think your guess of the machine running out
of memory is correct; that's my guess too but I just don't understand
why it happened. I can understand the scenario you described but actually
I omitted some details in the post to keep it short. I actually disabled
the elevator algorithm by substituting in my own elevator_noop_merge
function that simply always returns ELEVATOR_NO_MERGE. So each request
will only have one buffer_head hanging off it (unless my naive idea of
disabling the elevator algorithm didn't work?). It helped to prolong
the life of the machine a little more but the machine still died
eventually. I'm really confused. Any idea at all? Thank you for your
time and sorry again forgetting to mention your name about the book.
--
/Gong