svn commit: r340396 - in stable/12/sys: kern vm
Mark Johnston
markj at FreeBSD.org
Tue Nov 13 16:51:33 UTC 2018
Author: markj
Date: Tue Nov 13 16:51:30 2018
New Revision: 340396
URL: https://svnweb.freebsd.org/changeset/base/340396
Log:
MFC r339925:
Fix some problems that manifest when NUMA domain 0 is empty.
Approved by: re (gjb)
Modified:
stable/12/sys/kern/kern_cpuset.c
stable/12/sys/vm/uma_core.c
stable/12/sys/vm/vm_init.c
stable/12/sys/vm/vm_kern.c
stable/12/sys/vm/vm_page.c
stable/12/sys/vm/vm_pageout.c
Directory Properties:
stable/12/ (props changed)
Modified: stable/12/sys/kern/kern_cpuset.c
==============================================================================
--- stable/12/sys/kern/kern_cpuset.c Tue Nov 13 15:28:27 2018 (r340395)
+++ stable/12/sys/kern/kern_cpuset.c Tue Nov 13 16:51:30 2018 (r340396)
@@ -492,20 +492,29 @@ _domainset_create(struct domainset *domain, struct dom
}
/*
- * Are any of the domains in the mask empty? If so, silently
- * remove them. If only empty domains are present, we must
- * return failure.
+ * Are any of the domains in the mask empty? If so, silently
+ * remove them and update the domainset accordingly. If only empty
+ * domains are present, we must return failure.
*/
static bool
domainset_empty_vm(struct domainset *domain)
{
- int i, max;
+ int i, j, max;
max = DOMAINSET_FLS(&domain->ds_mask) + 1;
- for (i = 0; i < max; i++) {
- if (DOMAINSET_ISSET(i, &domain->ds_mask) &&
- VM_DOMAIN_EMPTY(i))
+ for (i = 0; i < max; i++)
+ if (DOMAINSET_ISSET(i, &domain->ds_mask) && VM_DOMAIN_EMPTY(i))
DOMAINSET_CLR(i, &domain->ds_mask);
+ domain->ds_cnt = DOMAINSET_COUNT(&domain->ds_mask);
+ max = DOMAINSET_FLS(&domain->ds_mask) + 1;
+ for (i = j = 0; i < max; i++) {
+ if (DOMAINSET_ISSET(i, &domain->ds_mask))
+ domain->ds_order[j++] = i;
+ else if (domain->ds_policy == DOMAINSET_POLICY_PREFER &&
+ domain->ds_prefer == i && domain->ds_cnt > 1) {
+ domain->ds_policy = DOMAINSET_POLICY_ROUNDROBIN;
+ domain->ds_prefer = -1;
+ }
}
return (DOMAINSET_EMPTY(&domain->ds_mask));
@@ -1378,7 +1387,7 @@ cpuset_setithread(lwpid_t id, int cpu)
/*
* Initialize static domainsets after NUMA information is available. This is
- * called very early during boot.
+ * called before memory allocators are initialized.
*/
void
domainset_init(void)
@@ -1407,7 +1416,7 @@ domainset_init(void)
void
domainset_zero(void)
{
- struct domainset *dset;
+ struct domainset *dset, *tmp;
mtx_init(&cpuset_lock, "cpuset", NULL, MTX_SPIN | MTX_RECURSE);
@@ -1422,8 +1431,9 @@ domainset_zero(void)
kernel_object->domain.dr_policy = _domainset_create(&domainset2, NULL);
/* Remove empty domains from the global policies. */
- LIST_FOREACH(dset, &cpuset_domains, ds_link)
- (void)domainset_empty_vm(dset);
+ LIST_FOREACH_SAFE(dset, &cpuset_domains, ds_link, tmp)
+ if (domainset_empty_vm(dset))
+ LIST_REMOVE(dset, ds_link);
}
/*
Modified: stable/12/sys/vm/uma_core.c
==============================================================================
--- stable/12/sys/vm/uma_core.c Tue Nov 13 15:28:27 2018 (r340395)
+++ stable/12/sys/vm/uma_core.c Tue Nov 13 16:51:30 2018 (r340396)
@@ -3608,29 +3608,30 @@ uma_zone_reserve_kva(uma_zone_t zone, int count)
void
uma_prealloc(uma_zone_t zone, int items)
{
+ struct vm_domainset_iter di;
uma_domain_t dom;
uma_slab_t slab;
uma_keg_t keg;
- int domain, slabs;
+ int domain, flags, slabs;
keg = zone_first_keg(zone);
if (keg == NULL)
return;
KEG_LOCK(keg);
slabs = items / keg->uk_ipers;
- domain = 0;
if (slabs * keg->uk_ipers < items)
slabs++;
+ flags = M_WAITOK;
+ vm_domainset_iter_policy_ref_init(&di, &keg->uk_dr, &domain, &flags);
while (slabs-- > 0) {
- slab = keg_alloc_slab(keg, zone, domain, M_WAITOK);
+ slab = keg_alloc_slab(keg, zone, domain, flags);
if (slab == NULL)
return;
MPASS(slab->us_keg == keg);
dom = &keg->uk_domain[slab->us_domain];
LIST_INSERT_HEAD(&dom->ud_free_slab, slab, us_link);
- do {
- domain = (domain + 1) % vm_ndomains;
- } while (VM_DOMAIN_EMPTY(domain));
+ if (vm_domainset_iter_policy(&di, &domain) != 0)
+ break;
}
KEG_UNLOCK(keg);
}
Modified: stable/12/sys/vm/vm_init.c
==============================================================================
--- stable/12/sys/vm/vm_init.c Tue Nov 13 15:28:27 2018 (r340395)
+++ stable/12/sys/vm/vm_init.c Tue Nov 13 16:51:30 2018 (r340396)
@@ -123,11 +123,17 @@ vm_mem_init(void *dummy)
domainset_init();
/*
- * Initializes resident memory structures. From here on, all physical
+ * Initialize resident memory structures. From here on, all physical
* memory is accounted for, and we use only virtual addresses.
*/
vm_set_page_size();
virtual_avail = vm_page_startup(virtual_avail);
+
+ /*
+ * Set an initial domain policy for thread0 so that allocations
+ * can work.
+ */
+ domainset_zero();
#ifdef UMA_MD_SMALL_ALLOC
/* Announce page availability to UMA. */
Modified: stable/12/sys/vm/vm_kern.c
==============================================================================
--- stable/12/sys/vm/vm_kern.c Tue Nov 13 15:28:27 2018 (r340395)
+++ stable/12/sys/vm/vm_kern.c Tue Nov 13 16:51:30 2018 (r340396)
@@ -800,7 +800,6 @@ kmem_bootstrap_free(vm_offset_t start, vm_size_t size)
vmd = vm_pagequeue_domain(m);
vm_domain_free_lock(vmd);
vm_phys_free_pages(m, 0);
- vmd->vmd_page_count++;
vm_domain_free_unlock(vmd);
vm_domain_freecnt_inc(vmd, 1);
Modified: stable/12/sys/vm/vm_page.c
==============================================================================
--- stable/12/sys/vm/vm_page.c Tue Nov 13 15:28:27 2018 (r340395)
+++ stable/12/sys/vm/vm_page.c Tue Nov 13 16:51:30 2018 (r340396)
@@ -855,11 +855,6 @@ vm_page_startup(vm_offset_t vaddr)
*/
vm_reserv_init();
#endif
- /*
- * Set an initial domain policy for thread0 so that allocations
- * can work.
- */
- domainset_zero();
return (vaddr);
}
Modified: stable/12/sys/vm/vm_pageout.c
==============================================================================
--- stable/12/sys/vm/vm_pageout.c Tue Nov 13 15:28:27 2018 (r340395)
+++ stable/12/sys/vm/vm_pageout.c Tue Nov 13 16:51:30 2018 (r340396)
@@ -2072,41 +2072,41 @@ vm_pageout_init(void)
static void
vm_pageout(void)
{
- int error;
- int i;
+ struct proc *p;
+ struct thread *td;
+ int error, first, i;
+ p = curproc;
+ td = curthread;
+
swap_pager_swap_init();
- snprintf(curthread->td_name, sizeof(curthread->td_name), "dom0");
- error = kthread_add(vm_pageout_laundry_worker, NULL, curproc, NULL,
- 0, 0, "laundry: dom0");
- if (error != 0)
- panic("starting laundry for domain 0, error %d", error);
- for (i = 1; i < vm_ndomains; i++) {
+ for (first = -1, i = 0; i < vm_ndomains; i++) {
if (VM_DOMAIN_EMPTY(i)) {
if (bootverbose)
printf("domain %d empty; skipping pageout\n",
i);
continue;
}
-
- error = kthread_add(vm_pageout_worker, (void *)(uintptr_t)i,
- curproc, NULL, 0, 0, "dom%d", i);
- if (error != 0) {
- panic("starting pageout for domain %d, error %d\n",
- i, error);
+ if (first == -1)
+ first = i;
+ else {
+ error = kthread_add(vm_pageout_worker,
+ (void *)(uintptr_t)i, p, NULL, 0, 0, "dom%d", i);
+ if (error != 0)
+ panic("starting pageout for domain %d: %d\n",
+ i, error);
}
error = kthread_add(vm_pageout_laundry_worker,
- (void *)(uintptr_t)i, curproc, NULL, 0, 0,
- "laundry: dom%d", i);
+ (void *)(uintptr_t)i, p, NULL, 0, 0, "laundry: dom%d", i);
if (error != 0)
- panic("starting laundry for domain %d, error %d",
- i, error);
+ panic("starting laundry for domain %d: %d", i, error);
}
- error = kthread_add(uma_reclaim_worker, NULL, curproc, NULL,
- 0, 0, "uma");
+ error = kthread_add(uma_reclaim_worker, NULL, p, NULL, 0, 0, "uma");
if (error != 0)
panic("starting uma_reclaim helper, error %d\n", error);
- vm_pageout_worker((void *)(uintptr_t)0);
+
+ snprintf(td->td_name, sizeof(td->td_name), "dom%d", first);
+ vm_pageout_worker((void *)(uintptr_t)first);
}
/*
More information about the svn-src-stable
mailing list