[Bug 275436] tmpfs does not honor memory limits on writes

From: <bugzilla-noreply_at_freebsd.org>
Date: Thu, 30 Nov 2023 22:37:00 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=275436

--- Comment #2 from Mike Karels <karels@freebsd.org> ---
(In reply to Konstantin Belousov from comment #1)
First, the primary purpose of this bug is to document that there is a problem
with writes exceeding the stated limit on the file system size.  The fact that
I can write multiple gigabytes after df shows remaining space of 0 indicates a
problem.

I had no expectation that this workaround would be a correct fix, or I would
have put it into a review.

I do think that the memory free target should be taken into account.  If tmpfs
attempts to use all of free memory, the VM system is likely to try to raise the
free memory, paging/swapping as needed.  btw, my original reason for looking at
this is that I misunderstood the meaning in the man page, which says that a
size of 0 represents "the available amount of memory (including main memory and
swap space)".  I assumed that this included all of main memory, which is
clearly excessive, and instead it means the currently-available memory.  But if
we actually use all of memory + swap, the system will be killing processes (in
this case, starting with my memory hog but then the shells, nfsd, and more). 
Note that under the circumstances I am testing, tmpfs refuses to create a new
file, but will write gigabytes to existing files.  This seems to be due to the
lack of any check on free space (whether stored or dynamically-computed) in the
write path, unlike file creation.  My goal was to adjust the default limit so
that it was reasonably safe, which I think also needs to be done.

I don't think my workaround introduces a problem with holes.  The
tmpfs_reg_resize routine is used only for writes, so the pages in the
calculation will actually be written and recorded in the vm_object.

I think that, for file systems with no specific limit, the available memory
limit needs to be shared by any tmpfs file systems.  They can't each use all of
memory + swap.  Also, it probably doesn't make sense for file systems with a
specific limit to attempt writes when there is insufficient memory available,
unless the limit they are given is supposed to be a commitment, allowing other
memory users to be killed.  (The workaround doesn't distinguish between file
systems with/without a specific size, in part because tmpfs_reg_resize doesn't
currently refer to the file system itself.)

Does tmpfs actually store a current/recent memory limit for file systems that
don't have a preset size?  If it did, maybe higher levels would block writes.
The size limit actually works for file systems with a non-zero size.  However,
a size limit would have to be refreshed periodically, or on demand.  df will
display an available size of 0, but statfs computes that on the fly.

-- 
You are receiving this mail because:
You are the assignee for the bug.