Index: vm/vm_phys.c =================================================================== --- vm/vm_phys.c (.../freebsd10/20131010/sys) (revision 261566) +++ vm/vm_phys.c (.../head/sys) (revision 261566) @@ -101,6 +101,12 @@ SYSCTL_OID(_vm, OID_AUTO, phys_segs, CTLTYPE_STRING | CTLFLAG_RD, NULL, 0, sysctl_vm_phys_segs, "A", "Phys Seg Info"); +#if MAXMEMDOM > 1 +static int vm_first_touch = 1; +SYSCTL_INT(_vm, OID_AUTO, numa_first_touch, CTLFLAG_RW, &vm_first_touch, 0, + "Use first touch NUMA policy rather than round-robin"); +#endif + SYSCTL_INT(_vm, OID_AUTO, ndomains, CTLFLAG_RD, &vm_ndomains, 0, "Number of physical memory domains available."); @@ -119,6 +125,8 @@ #if MAXMEMDOM > 1 struct thread *td; + if (vm_first_touch) + return (PCPU_GET(domain)); td = curthread; td->td_dom_rr_idx++; @@ -420,11 +428,11 @@ KASSERT(order < VM_NFREEORDER, ("vm_phys_alloc_pages: order %d is out of range", order)); + domain = vm_rr_selectdomain(); for (dom = 0; dom < vm_ndomains; dom++) { - domain = vm_rr_selectdomain(); for (flind = 0; flind < vm_nfreelists; flind++) { - m = vm_phys_alloc_domain_pages(domain, flind, pool, - order); + m = vm_phys_alloc_domain_pages((domain + dom) % + vm_ndomains, flind, pool, order); if (m != NULL) return (m); } @@ -449,9 +457,10 @@ KASSERT(order < VM_NFREEORDER, ("vm_phys_alloc_freelist_pages: order %d is out of range", order)); + domain = vm_rr_selectdomain(); for (dom = 0; dom < vm_ndomains; dom++) { - domain = vm_rr_selectdomain(); - m = vm_phys_alloc_domain_pages(domain, flind, pool, order); + m = vm_phys_alloc_domain_pages((dom + domain) % vm_ndomains, + flind, pool, order); if (m != NULL) return (m); } @@ -809,11 +818,13 @@ vm_phys_zero_pages_idle(void) { static struct vm_freelist *fl; - static int flind, oind, pind; + static int flind, oind, pind, domain; vm_page_t m, m_tmp; - int domain; - domain = vm_rr_selectdomain(); +#if MAXMEMDOM > 1 + domain++; + domain %= vm_ndomains; +#endif fl = vm_phys_free_queues[domain][0][0]; mtx_assert(&vm_page_queue_free_mtx, MA_OWNED); for (;;) { @@ -881,8 +892,8 @@ /* Compute the queue that is the best fit for npages. */ for (order = 0; (1 << order) < npages; order++); dom = 0; + domain = vm_rr_selectdomain(); restartdom: - domain = vm_rr_selectdomain(); for (flind = 0; flind < vm_nfreelists; flind++) { for (oind = min(order, VM_NFREEORDER - 1); oind < VM_NFREEORDER; oind++) { for (pind = 0; pind < VM_NFREEPOOL; pind++) { @@ -940,8 +951,11 @@ } } } - if (++dom < vm_ndomains) + if (++dom < vm_ndomains) { + domain++; + domain %= vm_ndomains; goto restartdom; + } return (NULL); done: for (m = m_ret; m < &m_ret[npages]; m = &m[1 << oind]) {