/* * The page_retire_thread loops forever, looking to see if there are * pages still waiting to be retired. */ static void page_retire_thread(void) { callb_cpr_t c; CALLB_CPR_INIT(&c, &pr_thread_mutex, callb_generic_cpr, "page_retire"); mutex_enter(&pr_thread_mutex); for (;;) { if (pr_enable && PR_KSTAT_PENDING) { /* * Sigh. It's SO broken how we have to try to shake * loose the holder of the page. Since we have no * idea who or what has it locked, we go bang on * every door in the city to try to locate it. */ kmem_reap(); seg_preap(); page_retire_hunt(page_retire_thread_cb); CALLB_CPR_SAFE_BEGIN(&c); (void) cv_timedwait(&pr_cv, &pr_thread_mutex, lbolt + pr_thread_shortwait); CALLB_CPR_SAFE_END(&c, &pr_thread_mutex); } else { CALLB_CPR_SAFE_BEGIN(&c); (void) cv_timedwait(&pr_cv, &pr_thread_mutex, lbolt + pr_thread_longwait); CALLB_CPR_SAFE_END(&c, &pr_thread_mutex); } } /*NOTREACHED*/ }
/* * Schedule rate for paging. * Rate is linear interpolation between * slowscan with lotsfree and fastscan when out of memory. */ static void schedpaging(void *arg) { spgcnt_t vavail; if (freemem < lotsfree + needfree + kmem_reapahead) kmem_reap(); if (freemem < lotsfree + needfree + seg_preapahead) seg_preap(); if (kcage_on && (kcage_freemem < kcage_desfree || kcage_needfree)) kcage_cageout_wakeup(); if (mutex_tryenter(&pageout_mutex)) { /* pageout() not running */ nscan = 0; vavail = freemem - deficit; if (vavail < 0) vavail = 0; if (vavail > lotsfree) vavail = lotsfree; /* * Fix for 1161438 (CRS SPR# 73922). All variables * in the original calculation for desscan were 32 bit signed * ints. As freemem approaches 0x0 on a system with 1 Gig or * more of memory, the calculation can overflow. When this * happens, desscan becomes negative and pageout_scanner() * stops paging out. */ if (needfree) { desscan = fastscan / RATETOSCHEDPAGING; } else { spgcnt_t faststmp, slowstmp, result; slowstmp = slowscan * vavail; faststmp = fastscan * (lotsfree - vavail); result = (slowstmp + faststmp) / nz(lotsfree) / RATETOSCHEDPAGING; desscan = (pgcnt_t)result; } pageout_ticks = min_pageout_ticks + (lotsfree - vavail) * (max_pageout_ticks - min_pageout_ticks) / nz(lotsfree); if (freemem < lotsfree + needfree || pageout_sample_cnt < pageout_sample_lim) { TRACE_1(TR_FAC_VM, TR_PAGEOUT_CV_SIGNAL, "pageout_cv_signal:freemem %ld", freemem); cv_signal(&proc_pageout->p_cv); } else { /* * There are enough free pages, no need to * kick the scanner thread. And next time * around, keep more of the `highly shared' * pages. */ cv_signal_pageout(); if (po_share > MIN_PO_SHARE) { po_share >>= 1; } }