Re: Current amd64 new error or warning from today's current with ruby r320323

From: Konstantin Belousov <kostikbel_at_gmail.com>
Date: Mon, 26 Jun 2017 23:41:53 +0300
On Mon, Jun 26, 2017 at 01:34:35PM -0700, Benno Rice wrote:
> 
> > On Jun 26, 2017, at 13:25, Konstantin Belousov <kostikbel_at_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_at_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_at_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
_at__at_ -1556,6 +1556,25 _at__at_ 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
_at__at_ -372,6 +372,8 _at__at_ 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
_at__at_ -1438,10 +1439,12 _at__at_ 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);
_at__at_ -1529,11 +1532,20 _at__at_ 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);
Received on Mon Jun 26 2017 - 18:41:59 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:41:12 UTC