Re: Questions: bforget & forgotten pages

Stephen C. Tweedie (sct@redhat.com)
Fri, 28 Aug 1998 11:57:33 +0100


Hi,

On Thu, 27 Aug 1998 09:43:33 -0400 (EDT), Kenneth Albanowski
<kjahds@kjahds.com> said:

> I finally figured out what was causing a bizarre "leak": the bforget
> function which is invoked by ext2/truncate.c -- and _only_ by that code,
> at least in 2.0.33. In the process of truncating a file, bforget is
> invoked on the discarded buffers, which removes the protected bits (thus
> turning the pages loose from the ram disk), and resets the device numbers
> to zero without moving the page to the free list. The former is just
> annoying, but the latter seems to have the fairly bizarre effect of
> leaving "zombie" clean buffers around that, as far as I can tell, will not
> be reclaimed or reused by anything short of try_to_free_buffer, or the
> inner machinations of refill_freelist.

That's right. refill_freelist() is the primary mechanism for reclaiming
buffers when we want to allocate new buffers, and try_to_free_buffer()
is the primary mechanism by which the rest of the memory management
system frees up buffers. That's all right and proper.
try_to_free_buffer() is called from linux/mm/filemap.c:shrink_mmap(),
which is where we do the main cache/buffer page scanning for memory
reclaim.

> So, two questions: can I replace bforget in the ext2 code with something
> else, brelse perhaps? (It's not obvious whether their semantics are
> identical.) Secondly, am I mistaken about forgotten pages, and are they
> reclaimable via some process I've missed?

First, I'd just keep bforget, but you might think about doing

if (!buf->b_count) {
remove_from_queues(buf);
put_last_free(buf);
clear_bit(BH_Touched, &buf->b_state);
try_to_free_buffer(buf, &buf, 6);
} else
refile_buffer(buf);

(untested!!) at the end of __bforget. That will attempt to immediately
reclaim the buffers after freeing them. If there are any other,
non-freeable buffers in the same page, then the forgotten buffer will
just be left on the free list but won't be completely deleted.

Second, I think you may well have missed the try_to_free_buffer() call
from shrink_mmap(). If not, then what exactly is it that you think we
should be doing but we're not?

> More interestingly, if you repeatedly create and truncate a file,
> you'll continually spawn more forgotten buffers.

If they have been cleaned and refiled, then they _should_ be reclaimed
by the normal mechanisms, but only when the memory is needed for
something else. Have you got evidence that this is not happening?

--Stephen

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html