mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
Page allocator: get rid of the list of cold pages
We have repeatedly discussed if the cold pages still have a point. There is one way to join the two lists: Use a single list and put the cold pages at the end and the hot pages at the beginning. That way a single list can serve for both types of allocations. The discussion of the RFC for this and Mel's measurements indicate that there may not be too much of a point left to having separate lists for hot and cold pages (see http://marc.info/?t=119492914200001&r=1&w=2). Signed-off-by: Christoph Lameter <clameter@sgi.com> Cc: Mel Gorman <mel@csn.ul.ie> Cc: Martin Bligh <mbligh@mbligh.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
5dc3318528
commit
3dfa5721f1
3 changed files with 39 additions and 48 deletions
|
@ -113,7 +113,7 @@ struct per_cpu_pages {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct per_cpu_pageset {
|
struct per_cpu_pageset {
|
||||||
struct per_cpu_pages pcp[2]; /* 0: hot. 1: cold */
|
struct per_cpu_pages pcp;
|
||||||
#ifdef CONFIG_NUMA
|
#ifdef CONFIG_NUMA
|
||||||
s8 expire;
|
s8 expire;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -901,24 +901,21 @@ static void drain_pages(unsigned int cpu)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct zone *zone;
|
struct zone *zone;
|
||||||
int i;
|
|
||||||
|
|
||||||
for_each_zone(zone) {
|
for_each_zone(zone) {
|
||||||
struct per_cpu_pageset *pset;
|
struct per_cpu_pageset *pset;
|
||||||
|
struct per_cpu_pages *pcp;
|
||||||
|
|
||||||
if (!populated_zone(zone))
|
if (!populated_zone(zone))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
pset = zone_pcp(zone, cpu);
|
pset = zone_pcp(zone, cpu);
|
||||||
for (i = 0; i < ARRAY_SIZE(pset->pcp); i++) {
|
|
||||||
struct per_cpu_pages *pcp;
|
|
||||||
|
|
||||||
pcp = &pset->pcp[i];
|
pcp = &pset->pcp;
|
||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
free_pages_bulk(zone, pcp->count, &pcp->list, 0);
|
free_pages_bulk(zone, pcp->count, &pcp->list, 0);
|
||||||
pcp->count = 0;
|
pcp->count = 0;
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -993,10 +990,13 @@ static void fastcall free_hot_cold_page(struct page *page, int cold)
|
||||||
arch_free_page(page, 0);
|
arch_free_page(page, 0);
|
||||||
kernel_map_pages(page, 1, 0);
|
kernel_map_pages(page, 1, 0);
|
||||||
|
|
||||||
pcp = &zone_pcp(zone, get_cpu())->pcp[cold];
|
pcp = &zone_pcp(zone, get_cpu())->pcp;
|
||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
__count_vm_event(PGFREE);
|
__count_vm_event(PGFREE);
|
||||||
list_add(&page->lru, &pcp->list);
|
if (cold)
|
||||||
|
list_add_tail(&page->lru, &pcp->list);
|
||||||
|
else
|
||||||
|
list_add(&page->lru, &pcp->list);
|
||||||
set_page_private(page, get_pageblock_migratetype(page));
|
set_page_private(page, get_pageblock_migratetype(page));
|
||||||
pcp->count++;
|
pcp->count++;
|
||||||
if (pcp->count >= pcp->high) {
|
if (pcp->count >= pcp->high) {
|
||||||
|
@ -1054,7 +1054,7 @@ again:
|
||||||
if (likely(order == 0)) {
|
if (likely(order == 0)) {
|
||||||
struct per_cpu_pages *pcp;
|
struct per_cpu_pages *pcp;
|
||||||
|
|
||||||
pcp = &zone_pcp(zone, cpu)->pcp[cold];
|
pcp = &zone_pcp(zone, cpu)->pcp;
|
||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
if (!pcp->count) {
|
if (!pcp->count) {
|
||||||
pcp->count = rmqueue_bulk(zone, 0,
|
pcp->count = rmqueue_bulk(zone, 0,
|
||||||
|
@ -1064,9 +1064,15 @@ again:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find a page of the appropriate migrate type */
|
/* Find a page of the appropriate migrate type */
|
||||||
list_for_each_entry(page, &pcp->list, lru)
|
if (cold) {
|
||||||
if (page_private(page) == migratetype)
|
list_for_each_entry_reverse(page, &pcp->list, lru)
|
||||||
break;
|
if (page_private(page) == migratetype)
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
list_for_each_entry(page, &pcp->list, lru)
|
||||||
|
if (page_private(page) == migratetype)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocate more to the pcp list if necessary */
|
/* Allocate more to the pcp list if necessary */
|
||||||
if (unlikely(&page->lru == &pcp->list)) {
|
if (unlikely(&page->lru == &pcp->list)) {
|
||||||
|
@ -1793,12 +1799,9 @@ void show_free_areas(void)
|
||||||
|
|
||||||
pageset = zone_pcp(zone, cpu);
|
pageset = zone_pcp(zone, cpu);
|
||||||
|
|
||||||
printk("CPU %4d: Hot: hi:%5d, btch:%4d usd:%4d "
|
printk("CPU %4d: hi:%5d, btch:%4d usd:%4d\n",
|
||||||
"Cold: hi:%5d, btch:%4d usd:%4d\n",
|
cpu, pageset->pcp.high,
|
||||||
cpu, pageset->pcp[0].high,
|
pageset->pcp.batch, pageset->pcp.count);
|
||||||
pageset->pcp[0].batch, pageset->pcp[0].count,
|
|
||||||
pageset->pcp[1].high, pageset->pcp[1].batch,
|
|
||||||
pageset->pcp[1].count);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2596,17 +2599,11 @@ inline void setup_pageset(struct per_cpu_pageset *p, unsigned long batch)
|
||||||
|
|
||||||
memset(p, 0, sizeof(*p));
|
memset(p, 0, sizeof(*p));
|
||||||
|
|
||||||
pcp = &p->pcp[0]; /* hot */
|
pcp = &p->pcp;
|
||||||
pcp->count = 0;
|
pcp->count = 0;
|
||||||
pcp->high = 6 * batch;
|
pcp->high = 6 * batch;
|
||||||
pcp->batch = max(1UL, 1 * batch);
|
pcp->batch = max(1UL, 1 * batch);
|
||||||
INIT_LIST_HEAD(&pcp->list);
|
INIT_LIST_HEAD(&pcp->list);
|
||||||
|
|
||||||
pcp = &p->pcp[1]; /* cold*/
|
|
||||||
pcp->count = 0;
|
|
||||||
pcp->high = 2 * batch;
|
|
||||||
pcp->batch = max(1UL, batch/2);
|
|
||||||
INIT_LIST_HEAD(&pcp->list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2619,7 +2616,7 @@ static void setup_pagelist_highmark(struct per_cpu_pageset *p,
|
||||||
{
|
{
|
||||||
struct per_cpu_pages *pcp;
|
struct per_cpu_pages *pcp;
|
||||||
|
|
||||||
pcp = &p->pcp[0]; /* hot list */
|
pcp = &p->pcp;
|
||||||
pcp->high = high;
|
pcp->high = high;
|
||||||
pcp->batch = max(1UL, high/4);
|
pcp->batch = max(1UL, high/4);
|
||||||
if ((high/4) > (PAGE_SHIFT * 8))
|
if ((high/4) > (PAGE_SHIFT * 8))
|
||||||
|
|
30
mm/vmstat.c
30
mm/vmstat.c
|
@ -337,7 +337,7 @@ void refresh_cpu_vm_stats(int cpu)
|
||||||
* Check if there are pages remaining in this pageset
|
* Check if there are pages remaining in this pageset
|
||||||
* if not then there is nothing to expire.
|
* if not then there is nothing to expire.
|
||||||
*/
|
*/
|
||||||
if (!p->expire || (!p->pcp[0].count && !p->pcp[1].count))
|
if (!p->expire || !p->pcp.count)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -352,11 +352,8 @@ void refresh_cpu_vm_stats(int cpu)
|
||||||
if (p->expire)
|
if (p->expire)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (p->pcp[0].count)
|
if (p->pcp.count)
|
||||||
drain_zone_pages(zone, p->pcp + 0);
|
drain_zone_pages(zone, &p->pcp);
|
||||||
|
|
||||||
if (p->pcp[1].count)
|
|
||||||
drain_zone_pages(zone, p->pcp + 1);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -693,20 +690,17 @@ static void zoneinfo_show_print(struct seq_file *m, pg_data_t *pgdat,
|
||||||
"\n pagesets");
|
"\n pagesets");
|
||||||
for_each_online_cpu(i) {
|
for_each_online_cpu(i) {
|
||||||
struct per_cpu_pageset *pageset;
|
struct per_cpu_pageset *pageset;
|
||||||
int j;
|
|
||||||
|
|
||||||
pageset = zone_pcp(zone, i);
|
pageset = zone_pcp(zone, i);
|
||||||
for (j = 0; j < ARRAY_SIZE(pageset->pcp); j++) {
|
seq_printf(m,
|
||||||
seq_printf(m,
|
"\n cpu: %i"
|
||||||
"\n cpu: %i pcp: %i"
|
"\n count: %i"
|
||||||
"\n count: %i"
|
"\n high: %i"
|
||||||
"\n high: %i"
|
"\n batch: %i",
|
||||||
"\n batch: %i",
|
i,
|
||||||
i, j,
|
pageset->pcp.count,
|
||||||
pageset->pcp[j].count,
|
pageset->pcp.high,
|
||||||
pageset->pcp[j].high,
|
pageset->pcp.batch);
|
||||||
pageset->pcp[j].batch);
|
|
||||||
}
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
seq_printf(m, "\n vm stats threshold: %d",
|
seq_printf(m, "\n vm stats threshold: %d",
|
||||||
pageset->stat_threshold);
|
pageset->stat_threshold);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue