Subject: Re: buffer starvation & the vnd driver
To: Bill Studenmund <>
From: R. C. Dowdeswell <>
List: tech-kern
Date: 09/02/1999 01:27:58
On 936231518 seconds since the Beginning of the UNIX epoch
Bill Studenmund wrote:

[ . . . ]

>The problem manifests itself after a period of use of the fs over the vnd.
>I've forgotten if the system just dies, or panics. But it's reproducable
>and related to activity. It dies trying to flush dirty pages.

Well, I'll chime in here with the basic symptoms.  (I don't have
the machine with me, but...)  It hangs.  ddb tells me that
msdosfs_bmap() calls getblk() calls bawrite() to write a block out,
which calls vndstrategy() which calls msdosfs_bmap() which calls
getblk() which hangs waiting for the previous getblk() to finish.
And then all disk activity stops.

The problem is common because the FAT chains are linear.  So, if the
block that I am flushing is after the block that I am trying to bmap
in the first place then I am guaranteed to need the FAT block that I
am trying to free space for.

>As best we can tell, the problem is that msdosfs needs to read in buffers
>in order to satisfy the VOP_BMAP call in vndstrategy (in order to say
>which blocks relate to the file, it has to read file system data, like the
>FAT). The problem is that there aren't enough free pages available to read
>in the file layout info in order to write the dirty blocks in memory.
>I think it's another manifestation of the starvation issue which arrises
>when you nfs mount a directory from your own system - not enough free
>memory to service a request which would free up memory.
>One suggestion Jason made is to set a low-water mark, and whenever we
>allocate buffers below that point, we go through and schedule writes for
>delayed-write buffers.

Some thoughts that I had a while ago, but I haven't looked at the code
recently (in completely disorganised form):

I think that a lot of the problem is caused because we are trying
to actually do the flushing in the same context as the getblk().

This problem shouldn't exist if we keep track of where we got the
blocks from in the first place.  I think from my reading of the
vnd code, though, that the information is lost between the layers.

I'm not convinced that we have truly run out of available buffers.
My problem will be seen any time a call to getblk() tries to
bawrite().  And, I think that it does that before it actually runs
out of space.

bawrite() simply calls VOP_BWRITE(bp) which should just call the
device's bwrite, which doesn't call bmap(), except in the case of

Sorry that these were pretty random, but I'm falling asleep.

 == Roland Dowdeswell                      http://www.Imrryr.ORG/~elric/  ==
 == The Unofficial NetBSD Web Pages        http://www.Imrryr.ORG/NetBSD/  ==
 == The NetBSD Project                            http://www.NetBSD.ORG/  ==