From: "Lorenzo Stoakes (ARM)" <ljs@kernel.org>
To: Josef Bacik <josef@toxicpanda.com>
Cc: Andrew Morton <akpm@linux-foundation.org>,
"Liam R. Howlett" <liam@infradead.org>,
David Hildenbrand <david@kernel.org>,
Vlastimil Babka <vbabka@kernel.org>,
Jann Horn <jannh@google.com>, Pedro Falcato <pfalcato@suse.de>,
Muchun Song <muchun.song@linux.dev>,
Oscar Salvador <osalvador@suse.de>,
linux-mm@kvack.org
Subject: Re: [PATCH 4/6] mm/mremap: restore VM_ACCOUNT if the unmap fails
Date: Mon, 2 Nov 2026 13:38:41 +0000 [thread overview]
Message-ID: <auiNiMvxR8U36BTH@gremlin> (raw)
In-Reply-To: <20261030-b4-mremap-pre-split-v1-4-c1829811aed0@toxicpanda.com>
On Fri, Oct 30, 2026 at 02:42:49PM +0000, Josef Bacik wrote:
> If the unmap at the end of an mremap() move fails, the source VMA stays
> without VM_ACCOUNT. Neither munmap() nor exit_mmap() uncharges it then, so
> the charge for all of its pages stays in vm_committed_as after the process
> is gone.
>
> unmap_source_vma() clears the flag on the whole source VMA before the unmap
> and sets it again on the remaining parts afterwards, but its error path
> returns without doing so.
Yeah this whole VMA_ACCOUNT_BIT removal/reinstatement is a total hack and I hate
it.
The real long-term fix is to change that to something not terrible I
think... :)
>
> This was reproduced with fault injection: each failure on an anonymous
> mapping left Committed_AS higher by the size of the whole VMA after
> everything was unmapped.
>
> Fix by setting VM_ACCOUNT again on everything in the range of the original
It'd be extremely pedantic to say 'VMA_ACCOUNT_BIT' here, but it's the
kernel, so here I am being _that_ nitty ;)
> VMA. A failed unmap may have split the VMA already, so walk the range.
>
> Fixes: 51df7bcb6151 ("mm/mremap: account memory on do_munmap() failure")
Again, this requires crazy memory pressure, fatal signal etc. etc. so yes,
no cc: stable is valid.
> Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Logically generally OK, but I want you to rework this as per below.
> ---
> mm/mremap.c | 15 +++++++++++++--
> 1 file changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/mm/mremap.c b/mm/mremap.c
> index 6f941aeb1b5f..256eac721a07 100644
> --- a/mm/mremap.c
> +++ b/mm/mremap.c
> @@ -1246,9 +1246,20 @@ static void unmap_source_vma(struct vma_remap_struct *vrm)
> vrm->vma = NULL; /* Invalidated. */
> vrm->vmi_needs_invalidate = true;
> if (err) {
> - /* OOM: unable to split vma, just get accounts right */
> - if (accountable_move)
> + /*
> + * OOM: unable to split vma, just get accounts right. Both the
> + * old and the new range remain mapped, so charge the range a
> + * second time, and reinstate the flag on all that is left of
> + * the VMA so the charge is returned when it gets unmapped.
> + */
This is quite schloppy. I don't think we need this bit.
> + if (accountable_move) {
> vm_acct_memory(len >> PAGE_SHIFT);
> + vma_iter_set(&vmi, vm_start);
> + for_each_vma_range(vmi, vma, vm_end) {
> + vma_start_write(vma);
> + vma_set_flags(vma, VMA_ACCOUNT_BIT);
> + }
> + }
I'd rather separate this out into its own helper. That also means you could
share code with the bit at the end?
Like:
static void vma_range_set_account(struct vma_iterator *vmi,
unsigned long start, unsigned long end)
{
struct vm_area_struct *vma;
vma_iter_set(vmi, start);
for_each_vma_range(*vmi, vma, end) {
vma_start_write(vma);
vma_set_flags(vma, VMA_ACCOUNT_BIT);
}
}
Then the above error path becomes:
if (err) {
/* OOM: unable to split vma, just get accounts right */
if (accountable_move) {
vm_acct_memory(len >> PAGE_SHIFT);
vma_range_set_account(&vmi, vm_start, vm_end);
}
return;
}
And on success at the end of the function you can reduce that bit to:
/*
* ...
* do_vmi_munmap() will have restored the VMI back to addr.
*/
if (accountable_move)
vma_range_set_account(&vmi, vm_start, vm_end);
Which is nice :)
> return;
> }
>
>
> --
> 2.55.0
>
--
Cheers, Lorenzo
next prev parent reply other threads:[~2026-11-02 13:38 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-30 14:42 [PATCH 0/6] mm/mremap: report a failed split before moving anything Josef Bacik
2026-10-30 14:42 ` [PATCH 1/6] mm/mremap: fix hugetlb reservation leak on partial move Josef Bacik
2026-11-02 13:13 ` Lorenzo Stoakes (ARM)
2026-10-30 14:42 ` [PATCH 2/6] selftests/mm: test a partial mremap() of hugetlb memory Josef Bacik
2026-11-02 13:14 ` Lorenzo Stoakes (ARM)
2026-10-30 14:42 ` [PATCH 3/6] mm/mremap: reaccount on unmap failure only if accounted Josef Bacik
2026-11-02 13:17 ` Lorenzo Stoakes (ARM)
2026-10-30 14:42 ` [PATCH 4/6] mm/mremap: restore VM_ACCOUNT if the unmap fails Josef Bacik
2026-11-02 13:38 ` Lorenzo Stoakes (ARM) [this message]
2026-10-30 14:42 ` [PATCH 5/6] selftests/mm: test mremap() with an old size of 0 Josef Bacik
2026-11-02 13:39 ` Lorenzo Stoakes (ARM)
2026-10-30 14:42 ` [PATCH 6/6] mm/mremap: split first so a failed split is reported Josef Bacik
2026-10-31 19:27 ` Jose A. Perez de Azpillaga
2026-11-02 13:57 ` Lorenzo Stoakes (ARM)
2026-11-02 12:50 ` [PATCH 0/6] mm/mremap: report a failed split before moving anything Lorenzo Stoakes (ARM)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=auiNiMvxR8U36BTH@gremlin \
--to=ljs@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=david@kernel.org \
--cc=jannh@google.com \
--cc=josef@toxicpanda.com \
--cc=liam@infradead.org \
--cc=linux-mm@kvack.org \
--cc=muchun.song@linux.dev \
--cc=osalvador@suse.de \
--cc=pfalcato@suse.de \
--cc=vbabka@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.