Date: Sat, 22 Nov 2025 15:48:08 +0200 From: Konstantin Belousov <kostikbel@gmail.com> To: Michal Meloun <mmel@freebsd.org> Cc: FreeBSD Current <freebsd-current@freebsd.org> Subject: Re: mmap( MAP_ANON) is broken on current. (was Still seeing Failed assertion: "p[i] == 0" on armv7 buildworld) Message-ID: <aSG_GJNR7L4Mx-e8@kib.kiev.ua> In-Reply-To: <07201c46-6fb4-4514-aa88-490830edb010@freebsd.org> References: <8657a2f4-cb32-49a5-bbf6-cd5a4394c7be@FreeBSD.org> <aSAklF9D8haCAaNU@kib.kiev.ua> <aSAq8Ds6nCA24YEI@kib.kiev.ua> <ab87cb06-0b54-431c-9529-1fa993e614ef@freebsd.org> <aSDDatRqKWZ3tUmt@kib.kiev.ua> <aSDFcWRx3vV86KvL@kib.kiev.ua> <07201c46-6fb4-4514-aa88-490830edb010@freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Sat, Nov 22, 2025 at 01:23:00PM +0100, Michal Meloun wrote: > > > On 21.11.2025 21:02, Konstantin Belousov wrote: > > On Fri, Nov 21, 2025 at 09:54:23PM +0200, Konstantin Belousov wrote: > > > On Fri, Nov 21, 2025 at 08:08:47PM +0100, Michal Meloun wrote: > > > > First, many thanks for your efforts, but this check doesn't trigger when the > > > > problem occurs > > > > > > > Hm, ok. This is a data point, in fact. > > > > > > > > > > > To be more precise, testing case > > > > on fresh kernel(d8bfcacd12aba73188c44a157c707908e275825d) > > > > with PMAP_DEBUG defined in pmap-v6.c and with > > > > trivial zero check for first page at this place -> > > > > https://cgit.freebsd.org/src/tree/contrib/jemalloc/src/pages.c#n281 > > > > > > > > causes this failure: > > > > > > > > __je_pages_map: addr: 0x0, ret: 0x3087b000, size: 4096, alignment: 4096, > > > > prot: 0x00000003, flags: 0x0C001002 > > > > __je_pages_map: i: 0, p[i]: 0xFFFFFFFF, p: 0x3087b000 > > > > __je_pages_map: i: 23, p[i]: 0x308E5F94, p: 0x3087b000 > > > > > > Could you, please, when the failure is detected, spawn 'procstat -v <pid>' > > > and dump the memory map of the process? To be clear, I want to see all > > > of this: > > > - the address of the mapping returned by mmap > > > - its size > > > - the location of the first non-zero byte > > > - memory map > > > > Also, regardless of the output above, please try this as a wild guess: > > > > diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c > > index 5b4517d2bf0c..5c6ed51706bf 100644 > > --- a/sys/vm/vm_object.c > > +++ b/sys/vm/vm_object.c > > @@ -2222,7 +2222,7 @@ vm_object_coalesce(vm_object_t prev_object, vm_ooffset_t prev_offset, > > * Remove any pages that may still be in the object from a previous > > * deallocation. > > */ > > - if (next_pindex < prev_object->size) { > > + if (true || next_pindex < prev_object->size) { > > vm_object_page_remove(prev_object, next_pindex, next_pindex + > > next_size, 0); > > #if 0 > > > I finally found the right way to obtain both parts of report in synchronized > and straightforward way. > The outputs from procstat -v are in the Outputs from procstat -v are in > attachments, I hope that the mailing list won't eat them. > These are without this patch. > > About this patch - this does not solve the problem, but it measurable > reduces its likelihood. So in both cases you reported below (skipped) the problem indeed appeared in the case where we extend existing mapping, potentially causing the object to reuse the dandling pages after the object' end. This must explain why the debugging patch did not catched anything. It is somewhat strange that the vm_object_coalesce() patch has the non-deterministic effect, but lets see. Below is the big hammer, disabling the extension for the anon mappings at all. Again, I want to know if it helps. This is a debugging aid, not a fix. It should cause large(r) fragmentation of the process map, and possibly much larger kernel memory use, but I hope it is usable for test. diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index 6b09552c5fee..6a1db58d2d13 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -1732,7 +1732,7 @@ vm_map_insert1(vm_map_t map, vm_object_t object, vm_ooffset_t offset, vm_object_clear_flag(object, OBJ_ONEMAPPING); VM_OBJECT_WUNLOCK(object); } - } else if ((prev_entry->eflags & ~MAP_ENTRY_USER_WIRED) == + } else if (false && (prev_entry->eflags & ~MAP_ENTRY_USER_WIRED) == protoeflags && (cow & (MAP_STACK_AREA | MAP_VN_EXEC)) == 0 && prev_entry->end == start && (prev_entry->cred == cred ||
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?aSG_GJNR7L4Mx-e8>
