Current amd64 new error or warning from today's current with ruby r320323
Konstantin Belousov
kostikbel at gmail.com
Mon Jun 26 20:42:00 UTC 2017
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
@@ -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);
More information about the freebsd-current
mailing list