Changeset View
Changeset View
Standalone View
Standalone View
head/sys/vm/vm_pageout.c
| Show First 20 Lines • Show All 146 Lines • ▼ Show 20 Lines | |||||
| #define VM_LAUNDER_RATE 10 | #define VM_LAUNDER_RATE 10 | ||||
| #define VM_INACT_SCAN_RATE 10 | #define VM_INACT_SCAN_RATE 10 | ||||
| static int vm_pageout_oom_seq = 12; | static int vm_pageout_oom_seq = 12; | ||||
| static int vm_pageout_update_period; | static int vm_pageout_update_period; | ||||
| static int disable_swap_pageouts; | static int disable_swap_pageouts; | ||||
| static int lowmem_period = 10; | static int lowmem_period = 10; | ||||
| static time_t lowmem_uptime; | |||||
| static int swapdev_enabled; | static int swapdev_enabled; | ||||
| static int vm_panic_on_oom = 0; | static int vm_panic_on_oom = 0; | ||||
| SYSCTL_INT(_vm, OID_AUTO, panic_on_oom, | SYSCTL_INT(_vm, OID_AUTO, panic_on_oom, | ||||
| CTLFLAG_RWTUN, &vm_panic_on_oom, 0, | CTLFLAG_RWTUN, &vm_panic_on_oom, 0, | ||||
| "panic on out of memory instead of killing the largest process"); | "panic on out of memory instead of killing the largest process"); | ||||
| ▲ Show 20 Lines • Show All 1,687 Lines • ▼ Show 20 Lines | if (bigproc != NULL) { | ||||
| PROC_LOCK(bigproc); | PROC_LOCK(bigproc); | ||||
| killproc(bigproc, "out of swap space"); | killproc(bigproc, "out of swap space"); | ||||
| sched_nice(bigproc, PRIO_MIN); | sched_nice(bigproc, PRIO_MIN); | ||||
| _PRELE(bigproc); | _PRELE(bigproc); | ||||
| PROC_UNLOCK(bigproc); | PROC_UNLOCK(bigproc); | ||||
| } | } | ||||
| } | } | ||||
| static void | static bool | ||||
| vm_pageout_lowmem(struct vm_domain *vmd) | vm_pageout_lowmem(void) | ||||
| { | { | ||||
| static int lowmem_ticks = 0; | |||||
| int last; | |||||
| if (vmd == VM_DOMAIN(0) && | last = atomic_load_int(&lowmem_ticks); | ||||
| time_uptime - lowmem_uptime >= lowmem_period) { | while ((u_int)(ticks - last) / hz >= lowmem_period) { | ||||
| if (atomic_fcmpset_int(&lowmem_ticks, &last, ticks) == 0) | |||||
| continue; | |||||
| /* | /* | ||||
| * Decrease registered cache sizes. | * Decrease registered cache sizes. | ||||
| */ | */ | ||||
| SDT_PROBE0(vm, , , vm__lowmem_scan); | SDT_PROBE0(vm, , , vm__lowmem_scan); | ||||
| EVENTHANDLER_INVOKE(vm_lowmem, VM_LOW_PAGES); | EVENTHANDLER_INVOKE(vm_lowmem, VM_LOW_PAGES); | ||||
| /* | /* | ||||
| * We do this explicitly after the caches have been | * We do this explicitly after the caches have been | ||||
| * drained above. | * drained above. | ||||
| */ | */ | ||||
| uma_reclaim(); | uma_reclaim(); | ||||
| lowmem_uptime = time_uptime; | return (true); | ||||
| } | } | ||||
| return (false); | |||||
| } | } | ||||
| static void | static void | ||||
| vm_pageout_worker(void *arg) | vm_pageout_worker(void *arg) | ||||
| { | { | ||||
| struct vm_domain *vmd; | struct vm_domain *vmd; | ||||
| u_int ofree; | |||||
| int addl_shortage, domain, shortage; | int addl_shortage, domain, shortage; | ||||
| bool target_met; | bool target_met; | ||||
| domain = (uintptr_t)arg; | domain = (uintptr_t)arg; | ||||
| vmd = VM_DOMAIN(domain); | vmd = VM_DOMAIN(domain); | ||||
| shortage = 0; | shortage = 0; | ||||
| target_met = true; | target_met = true; | ||||
| ▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | if (vm_paging_needed(vmd, vmd->vmd_free_count)) { | ||||
| VM_CNT_INC(v_pdwakeups); | VM_CNT_INC(v_pdwakeups); | ||||
| } | } | ||||
| /* Prevent spurious wakeups by ensuring that wanted is set. */ | /* Prevent spurious wakeups by ensuring that wanted is set. */ | ||||
| atomic_store_int(&vmd->vmd_pageout_wanted, 1); | atomic_store_int(&vmd->vmd_pageout_wanted, 1); | ||||
| /* | /* | ||||
| * Use the controller to calculate how many pages to free in | * Use the controller to calculate how many pages to free in | ||||
| * this interval, and scan the inactive queue. | * this interval, and scan the inactive queue. If the lowmem | ||||
| * handlers appear to have freed up some pages, subtract the | |||||
| * difference from the inactive queue scan target. | |||||
| */ | */ | ||||
| shortage = pidctrl_daemon(&vmd->vmd_pid, vmd->vmd_free_count); | shortage = pidctrl_daemon(&vmd->vmd_pid, vmd->vmd_free_count); | ||||
| if (shortage > 0) { | if (shortage > 0) { | ||||
| vm_pageout_lowmem(vmd); | ofree = vmd->vmd_free_count; | ||||
| if (vm_pageout_lowmem() && vmd->vmd_free_count > ofree) | |||||
| shortage -= min(vmd->vmd_free_count - ofree, | |||||
| (u_int)shortage); | |||||
| target_met = vm_pageout_scan_inactive(vmd, shortage, | target_met = vm_pageout_scan_inactive(vmd, shortage, | ||||
| &addl_shortage); | &addl_shortage); | ||||
| } else | } else | ||||
| addl_shortage = 0; | addl_shortage = 0; | ||||
| /* | /* | ||||
| * Scan the active queue. A positive value for shortage | * Scan the active queue. A positive value for shortage | ||||
| * indicates that we must aggressively deactivate pages to avoid | * indicates that we must aggressively deactivate pages to avoid | ||||
| ▲ Show 20 Lines • Show All 159 Lines • Show Last 20 Lines | |||||