1、pcp->high大小的计算

110 阅读1分钟
static void pageset_update(struct per_cpu_pages *pcp, unsigned long high,
                unsigned long batch)
{
       /* start with a fail safe value for batch */
        pcp->batch = 1;
        smp_wmb();

       /* Update high, then batch, in order */
        pcp->high = high;
        smp_wmb();

        pcp->batch = batch;
}

static void pageset_set_high(struct per_cpu_pageset *p,
                                unsigned long high)
{
        unsigned long batch = max(1UL, high / 4);
        if ((high / 4) > (PAGE_SHIFT * 8))
                batch = PAGE_SHIFT * 8;

        pageset_update(&p->pcp, high, batch);
}

static void pageset_set_batch(struct per_cpu_pageset *p, unsigned long batch)
{
        pageset_update(&p->pcp, 6 * batch, max(1UL, 1 * batch));
}

// 默认percpu_pagelist_fraction为0,走pageset_set_batch,否则走pageset_set_high
static void pageset_set_high_and_batch(struct zone *zone,
                                       struct per_cpu_pageset *pcp)
{
        if (percpu_pagelist_fraction)
                pageset_set_high(pcp,
                        (zone->managed_pages /
                                percpu_pagelist_fraction));
        else
                pageset_set_batch(pcp, zone_batchsize(zone));
}

// 通过/proc/sys/vm/percpu_pagelist_fraction进行设置,默认percpu_pagelist_fraction为0
int percpu_pagelist_fraction_sysctl_handler(struct ctl_table *table, int write,
        void __user *buffer, size_t *length, loff_t *ppos)
{
        struct zone *zone;
        int old_percpu_pagelist_fraction;
        int ret;

        mutex_lock(&pcp_batch_high_lock);
        old_percpu_pagelist_fraction = percpu_pagelist_fraction;

        ret = proc_dointvec_minmax(table, write, buffer, length, ppos);
        if (!write || ret < 0)
                goto out;

        /* Sanity checking to avoid pcp imbalance */
        if (percpu_pagelist_fraction &&
            percpu_pagelist_fraction < MIN_PERCPU_PAGELIST_FRACTION) {
                percpu_pagelist_fraction = old_percpu_pagelist_fraction;
                ret = -EINVAL;
                goto out;
        }

        /* No change? */
        if (percpu_pagelist_fraction == old_percpu_pagelist_fraction)
                goto out;

        for_each_populated_zone(zone) {
                unsigned int cpu;

                for_each_possible_cpu(cpu)
                        pageset_set_high_and_batch(zone,
                                        per_cpu_ptr(zone->pageset, cpu));
        }
out:
        mutex_unlock(&pcp_batch_high_lock);
        return ret;
}

// 初始化时进行设置,默认
static void __meminit zone_pageset_init(struct zone *zone, int cpu)
{
        struct per_cpu_pageset *pcp = per_cpu_ptr(zone->pageset, cpu);

        pageset_init(pcp);
        pageset_set_high_and_batch(zone, pcp);
}

选一台qemu机器打印相关参数,pageset_set_high_and_batch=0, zone->managed_pages=117836, pcp->high=186,zone_batchsize(zone)=31。