Date: Sun, 2 Sep 2018 18:29:39 +0000 (UTC) From: Alan Cox <alc@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r338431 - head/sys/vm Message-ID: <201809021829.w82ITdvi047687@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: alc Date: Sun Sep 2 18:29:38 2018 New Revision: 338431 URL: https://svnweb.freebsd.org/changeset/base/338431 Log: Recent changes have created, for the first time, physical memory segments that can be coalesced. To be clear, fragmentation of phys_avail[] is not the cause. This fragmentation of vm_phys_segs[] arises from the "special" calls to vm_phys_add_seg(), in other words, not those that derive directly from phys_avail[], but those that we create for the initial kernel page table pages and now for the kernel and modules loaded at boot time. Since we sometimes iterate over the physical memory segments, coalescing these segments at initialization time is a worthwhile change. Reviewed by: kib, markj Approved by: re (rgrimes) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D16976 Modified: head/sys/vm/vm_phys.c Modified: head/sys/vm/vm_phys.c ============================================================================== --- head/sys/vm/vm_phys.c Sun Sep 2 17:02:13 2018 (r338430) +++ head/sys/vm/vm_phys.c Sun Sep 2 18:29:38 2018 (r338431) @@ -460,7 +460,7 @@ void vm_phys_init(void) { struct vm_freelist *fl; - struct vm_phys_seg *seg; + struct vm_phys_seg *end_seg, *prev_seg, *seg, *tmp_seg; u_long npages; int dom, flind, freelist, oind, pind, segind; @@ -544,6 +544,29 @@ vm_phys_init(void) ("vm_phys_init: DEFAULT flind < 0")); } seg->free_queues = &vm_phys_free_queues[seg->domain][flind]; + } + + /* + * Coalesce physical memory segments that are contiguous and share the + * same per-domain free queues. + */ + prev_seg = vm_phys_segs; + seg = &vm_phys_segs[1]; + end_seg = &vm_phys_segs[vm_phys_nsegs]; + while (seg < end_seg) { + if (prev_seg->end == seg->start && + prev_seg->free_queues == seg->free_queues) { + prev_seg->end = seg->end; + KASSERT(prev_seg->domain == seg->domain, + ("vm_phys_init: free queues cannot span domains")); + vm_phys_nsegs--; + end_seg--; + for (tmp_seg = seg; tmp_seg < end_seg; tmp_seg++) + *tmp_seg = *(tmp_seg + 1); + } else { + prev_seg = seg; + seg++; + } } /*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201809021829.w82ITdvi047687>