Initialization of the Hotn Cold Cache

I have already mentioned the per-CPU (or hot-n-cold) cache in Section 3.2.2.. Here we deal with the initialization of the associated data structures and the calculation of the "watermarks"used to control cache filling behavior.

zone_pcp_init is responsible for initializing the cache. The kernel calls the function from free_area_init_nodes, which is, in turn, invoked during boot on both IA-32 and AMD64.

mm/page_alloc.c static _devinit void zone_pcp_init(struct zone *zone)

int cpu;

unsigned long batch = zone_batchsize(zone);

setup_pageset(zone_pcp(zone,cpu), batch);

if (zone->present_pages)

printk(KERN_DEBUG " %s zone: %lu pages, LIFO batch:%lu\n", zone->name, zone->present_pages, batch);

Once the batch size (which is the basis for calculating the minimum and maximum fill level) has been determined with zone_batchsize, the code iterates over all CPUs in the system and invokes setup_pageset to fill the constants of each per_cpu_pageset instance. The zone_pcp macro used when this function is invoked selects the pageset instance of the zone associated with the CPU currently being examined.

Let us take a closer look at how the watermark is calculated. mm/page_alloc.c static int _devinit zone_batchsize(struct zone *zone)

int batch;

batch = zone->present_pages / 1024; if (batch * PAGE_SIZE > 512 * 1024)

batch = (512 * 1024) / PAGE_SIZE; batch /= 4; if (batch < 1)

batch = (1 << (fls(batch + batch/2)-1)) - 1; return batch;

The code calculates batch so that it corresponds to roughly 25 percent of a thousandth of the pages present in the zone. The shift operation also ensures that the value calculated has the form 2n — 1 because it has been established empirically that this minimizes cache aliasing effects for most system loads. fls is a machine-specific operation to yield the last set bit of a value. Note that this alignment will cause the resulting values to deviate from 25 percent of one-thousandth the zones pages. The maximal deviation arises for that case batch = 22. Since 22 + 11 — 1 = 32, fls will find bit 5 as last set bit in the number, and 1 << 5-1 = 31. Because the deviation will usually be smaller, it can be neglected for all practical purposes.

The batch size does not increase when the memory in the zone exceeds 512 MiB. For systems with a page size of 4,096 KiB, for instance, this limit is reached when more than 131,072 pages are present. Figure 3-17 shows how the batch size evolves with the number of pages present in a zone.

The batch value makes sense when we consider how batch is used to calculate the cache limits in setup_pageset.

mm/page_alloc.c inline void setup_pageset(struct per_cpu_pageset *p, unsigned long batch) {

struct per_cpu_pages *pcp;

INIT_LIST_HEAD(&pcp->list);

INIT_LIST_HEAD(&pcp->list);

Zone memory [MiB] Pages in Zone

Continue reading here: Figure 317 Batch sizes dependent on the amount of memory present lefthand side on the zone for various page sizes The graph on the righthand side shows the dependency against the number of pages present in a zone

Was this article helpful?

0 0