Index: sys/vm/vm_glue.c =================================================================== --- sys/vm/vm_glue.c +++ sys/vm/vm_glue.c @@ -68,6 +68,7 @@ #include #include +#include #include #include #include @@ -298,7 +299,7 @@ struct kstack_cache_entry *kstack_cache; static int kstack_cache_size = 128; -static int kstacks; +static int kstacks, kstack_domain_iter; static struct mtx kstack_cache_mtx; MTX_SYSINIT(kstack_cache, &kstack_cache_mtx, "kstkch", MTX_DEF); @@ -369,6 +370,17 @@ return (0); } + /* + * Ensure that kstack objects can draw pages from any memory + * domain. Otherwise a local memory shortage can block a process + * swap-in. + */ + if (vm_ndomains > 1) { + ksobj->domain.dr_policy = DOMAINSET_ROUNDROBIN(); + ksobj->domain.dr_iter = atomic_fetchadd_int(&kstack_domain_iter, + 1); + } + atomic_add_int(&kstacks, 1); if (KSTACK_GUARD_PAGES != 0) { pmap_qremove(ks, KSTACK_GUARD_PAGES); Index: sys/vm/vm_swapout.c =================================================================== --- sys/vm/vm_swapout.c +++ sys/vm/vm_swapout.c @@ -742,7 +742,7 @@ /* * Limit swapper to swap in one non-WKILLED process in MAXSLP/2 * interval, assuming that there is: - * - no memory shortage; + * - no global memory shortage; * - no parallel swap-ins; * - no other swap-ins in the current SWAPIN_INTERVAL. */ @@ -750,7 +750,7 @@ swapper_wkilled_only(void) { - return (vm_page_count_min() || swap_inprogress > 0 || + return (vm_page_count_min_set(&all_domains) || swap_inprogress > 0 || (u_int)(ticks - last_swapin) < SWAPIN_INTERVAL); }