示例#1
0
/*
 * 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*/
}
示例#2
0
/*
 * 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;
            }
        }