svn commit: r338431 - head/sys/vm
Alan Cox
alc at FreeBSD.org
Sun Sep 2 18:29:39 UTC 2018
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++;
+ }
}
/*
More information about the svn-src-all
mailing list