Index: sys/arch/i386/i386/machdep.c =================================================================== RCS file: /cvsroot/src/sys/arch/i386/i386/machdep.c,v retrieving revision 1.774 diff -u -r1.774 machdep.c --- sys/arch/i386/i386/machdep.c 23 Dec 2016 09:24:57 -0000 1.774 +++ sys/arch/i386/i386/machdep.c 26 Dec 2016 15:22:16 -0000 @@ -1037,30 +1037,46 @@ static void init386_msgbuf(void) { - /* Message buffer is located at end of core. */ - psize_t reqsz = round_page(MSGBUFSIZE); - psize_t sz = 0; + /* Message buffer is located at end of core. */ + psize_t sz = round_page(MSGBUFSIZE); + psize_t reqsz = sz; + uvm_physseg_t x; + +search_again: + for (x = uvm_physseg_get_first(); + uvm_physseg_valid_p(x); + x = uvm_physseg_get_next(x)) { + if (ctob(uvm_physseg_get_avail_end(x)) == avail_end) { + break; + } + } + if (uvm_physseg_valid_p(x) == false) + panic("init386: can't find end of memory"); - for (sz = 0; sz < reqsz; sz += PAGE_SIZE) { - paddr_t stolenpa; + /* Shrink so it'll fit in the last segment. */ + if (uvm_physseg_get_avail_end(x) - uvm_physseg_get_avail_start(x) < atop(sz)) + sz = ctob(uvm_physseg_get_avail_end(x) - uvm_physseg_get_avail_start(x)); - if (!uvm_page_physget(&stolenpa)) - break; + uvm_physseg_unplug(uvm_physseg_get_end(x) - atop(sz), atop(sz)); + msgbuf_p_seg[msgbuf_p_cnt].sz = sz; + msgbuf_p_seg[msgbuf_p_cnt++].paddr = ctob(uvm_physseg_get_avail_end(x)); - if (stolenpa == (msgbuf_p_seg[msgbuf_p_cnt].paddr - + PAGE_SIZE)) { - /* contiguous: append it to current buf alloc */ - msgbuf_p_seg[msgbuf_p_cnt].sz += PAGE_SIZE; - } else { - /* non-contiguous: start a new msgbuf seg */ - msgbuf_p_seg[msgbuf_p_cnt].sz = PAGE_SIZE; - msgbuf_p_seg[msgbuf_p_cnt++].paddr = stolenpa; - } + /* Now find where the new avail_end is. */ + avail_end = ctob(uvm_physseg_get_avail_end(x)); + + if (sz == reqsz) + return; + + reqsz -= sz; + if (msgbuf_p_cnt == VM_PHYSSEG_MAX) { + /* No more segments available, bail out. */ + printf("WARNING: MSGBUFSIZE (%zu) too large, using %zu.\n", + (size_t)MSGBUFSIZE, (size_t)(MSGBUFSIZE - reqsz)); + return; } - if (sz != reqsz) - printf("%s: could only allocate %"PRIxPSIZE" bytes of requested" - " %"PRIxPSIZE" bytes\n", __func__, sz, reqsz); + sz = reqsz; + goto search_again; } #ifndef XEN