Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 26 Jun 2017 23:41:53 +0300
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        Benno Rice <benno@jeamland.net>
Cc:        Benjamin Kaduk <bjkfbsd@gmail.com>, Manfred Antar <null@pozo.com>, FreeBSD Current <freebsd-current@freebsd.org>
Subject:   Re: Current amd64 new error or warning from today's current with ruby r320323
Message-ID:  <20170626204153.GA3437@kib.kiev.ua>
In-Reply-To: <CC95ECFF-AB66-4D75-B937-045F4CB95283@jeamland.net>
References:  <20170625020441.GT3437@kib.kiev.ua> <219E6B59-EF90-443D-8B53-4C39C4D6CFBD@pozo.com> <20170625134133.GA3437@kib.kiev.ua> <3FEA16E1-673F-4C58-8362-C1DCC0680698@pozo.com> <20170625145008.GB3437@kib.kiev.ua> <D94B09A1-9090-4C6A-8EC4-19D2AFBBA316@pozo.com> <20170625164115.GD3437@kib.kiev.ua> <CAJ5_RoDd8%2BOXPfeQ10U3f3-ZozhshWBUXdSVFpnx_ZkhO_n4bw@mail.gmail.com> <20170626202524.GY3437@kib.kiev.ua> <CC95ECFF-AB66-4D75-B937-045F4CB95283@jeamland.net>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, Jun 26, 2017 at 01:34:35PM -0700, Benno Rice wrote:
> 
> > On Jun 26, 2017, at 13:25, Konstantin Belousov <kostikbel@gmail.com> wrote:
> > 
> > On Mon, Jun 26, 2017 at 02:53:14PM -0500, Benjamin Kaduk wrote:
> >> On Sun, Jun 25, 2017 at 11:41 AM, Konstantin Belousov <kostikbel@gmail.com>
> >> wrote:
> >> 
> >>> No need, I understood why MAP_STACK failed in this case, thanks to the
> >>> ktrace log. This is indeed something ruby-specific, or rather, triggered
> >>> by ruby special use of libthr. It is not related to the main stack
> >>> split.
> >>> 
> >>> It seems that ruby requested very small stack for a new thread, only 5
> >>> pages in size.  This size caused the stack gap to be correctly calculated
> >>> as having zero size, because the whole stack is allocated by initial grow.
> >>> But then there is no space for the guard page, which caused mapping failure
> >>> for it, and overall stack mapping failure.
> >>> 
> >>> Try this.
> >>> https://people.freebsd.org/~kib/misc/vm2.2.patch
> >>> 
> >>> 
> >> I managed to get the "Cannot allocate red zone for initial thread" at the
> >> start of installworld (doing CC feature detection, IIRC) going from r306247
> >> to r320328.
> >> 
> >> Is it worth trying that patch out?
> > 
> > Ensure that you run a kernel past r320344 and then show me ktrace of
> > the failing process.
> 
> So I???m running r320364 with a ZFS root:
> 
> > uname -a
> FreeBSD bjrbsd 12.0-CURRENT FreeBSD 12.0-CURRENT #0 r320364: Mon Jun 26 12:35:03 PDT 2017     benno@bjrbsd:/src/obj/src/freebsd/sys/GENERIC-NODEBUG  amd64
> 
> While upgrading I discovered that the zfs command works fine in multiuser but fails in single-user in the way described above:
> 
> # zfs mount -a
> Fatal error 'Cannot allocate red zone for initial thread' at line 393 in file /src/freebsd/lib(something)/thread/thr_init.c (errno = 12)
> Abort trap (core dumped)
> 
> I booted into single-user and ran zfs under ktrace and I???ve put the results up for you:
> 
> https://people.freebsd.org/~benno/ktrace.out.txt
> https://people.freebsd.org/~benno/ktrace.out
> https://people.freebsd.org/~benno/zfs.core

Try this.  Even if it helps, the patch is being actively discussed and
may be not in its final form.

diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index 7b4a86dffd8..2766454d825 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -1556,6 +1556,25 @@ again:
 	return (result);
 }
 
+int
+vm_map_find_min(vm_map_t map, vm_object_t object, vm_ooffset_t offset,
+    vm_offset_t *addr, vm_size_t length, vm_offset_t min_addr,
+    vm_offset_t max_addr, int find_space, vm_prot_t prot, vm_prot_t max,
+    int cow)
+{
+	vm_offset_t hint;
+	int rv;
+
+	hint = *addr;
+	for (;;) {
+		rv = vm_map_find(map, object, offset, addr, length, max_addr,
+		    find_space, prot, max, cow);
+		if (rv == KERN_SUCCESS || hint == 0 || min_addr >= hint)
+			return (rv);
+		*addr = min_addr;
+	}
+}
+
 /*
  *	vm_map_simplify_entry:
  *
diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h
index 2c89e1d73d4..78f3f31c226 100644
--- a/sys/vm/vm_map.h
+++ b/sys/vm/vm_map.h
@@ -372,6 +372,8 @@ vm_map_t vm_map_create(pmap_t, vm_offset_t, vm_offset_t);
 int vm_map_delete(vm_map_t, vm_offset_t, vm_offset_t);
 int vm_map_find(vm_map_t, vm_object_t, vm_ooffset_t, vm_offset_t *, vm_size_t,
     vm_offset_t, int, vm_prot_t, vm_prot_t, int);
+int vm_map_find_min(vm_map_t, vm_object_t, vm_ooffset_t, vm_offset_t *,
+    vm_size_t, vm_offset_t, vm_offset_t, int, vm_prot_t, vm_prot_t, int);
 int vm_map_fixed(vm_map_t, vm_object_t, vm_ooffset_t, vm_offset_t, vm_size_t,
     vm_prot_t, vm_prot_t, int);
 int vm_map_findspace (vm_map_t, vm_offset_t, vm_size_t, vm_offset_t *);
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
index 4d8f6ad9ed7..24360d422e3 100644
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -1438,10 +1439,12 @@ vm_mmap_object(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot,
     vm_prot_t maxprot, int flags, vm_object_t object, vm_ooffset_t foff,
     boolean_t writecounted, struct thread *td)
 {
-	boolean_t fitit;
+	boolean_t curmap, fitit;
+	vm_offset_t max_addr;
 	int docow, error, findspace, rv;
 
-	if (map == &td->td_proc->p_vmspace->vm_map) {
+	curmap = map == &td->td_proc->p_vmspace->vm_map;
+	if (curmap) {
 		PROC_LOCK(td->td_proc);
 		if (map->size + size > lim_cur_proc(td->td_proc, RLIMIT_VMEM)) {
 			PROC_UNLOCK(td->td_proc);
@@ -1529,11 +1532,20 @@ vm_mmap_object(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot,
 			    MAP_ALIGNMENT_SHIFT);
 		else
 			findspace = VMFS_OPTIMAL_SPACE;
-		rv = vm_map_find(map, object, foff, addr, size,
+		max_addr = 0;
 #ifdef MAP_32BIT
-		    flags & MAP_32BIT ? MAP_32BIT_MAX_ADDR :
+		if ((flags & MAP_32BIT) != 0)
+			max_addr = MAP_32BIT_MAX_ADDR;
 #endif
-		    0, findspace, prot, maxprot, docow);
+		if (curmap) {
+			rv = vm_map_find_min(map, object, foff, addr, size,
+			    round_page((vm_offset_t)td->td_proc->p_vmspace->
+			    vm_daddr + lim_max(td, RLIMIT_DATA)), max_addr,
+			    findspace, prot, maxprot, docow);
+		} else {
+			rv = vm_map_find(map, object, foff, addr, size,
+			    max_addr, findspace, prot, maxprot, docow);
+		}
 	} else {
 		rv = vm_map_fixed(map, object, foff, *addr, size,
 		    prot, maxprot, docow);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20170626204153.GA3437>