From: Oleg Nesterov Introduces a __mod_page_state(offset, delta) function and converts mod_page_state() to use it. Unexports and staticizes page_states per cpu variable. text data bss dec hex filename 1818704 615884 0 2434588 25261c vmlinux-old 1817632 615884 0 2433516 2521ec vmlinux-new 1072 bytes. (Adds 64 bytes without CONFIG_SMP). Signed-off-by: Oleg Nesterov Signed-off-by: Andrew Morton --- 25-akpm/include/linux/page-flags.h | 34 +++++++++++++--------------------- 25-akpm/mm/page_alloc.c | 16 ++++++++++++++-- 2 files changed, 27 insertions(+), 23 deletions(-) diff -puN include/linux/page-flags.h~uninline-mod_page_state include/linux/page-flags.h --- 25/include/linux/page-flags.h~uninline-mod_page_state 2005-01-16 14:44:25.730225160 -0800 +++ 25-akpm/include/linux/page-flags.h 2005-01-16 14:44:25.735224400 -0800 @@ -133,40 +133,32 @@ struct page_state { unsigned long pgrotated; /* pages rotated to tail of the LRU */ }; -DECLARE_PER_CPU(struct page_state, page_states); - extern void get_page_state(struct page_state *ret); extern void get_full_page_state(struct page_state *ret); extern unsigned long __read_page_state(unsigned offset); +extern void __mod_page_state(unsigned offset, unsigned long delta); #define read_page_state(member) \ __read_page_state(offsetof(struct page_state, member)) -#define mod_page_state(member, delta) \ - do { \ - unsigned long flags; \ - local_irq_save(flags); \ - __get_cpu_var(page_states).member += (delta); \ - local_irq_restore(flags); \ - } while (0) - +#define mod_page_state(member, delta) \ + __mod_page_state(offsetof(struct page_state, member), (delta)) #define inc_page_state(member) mod_page_state(member, 1UL) #define dec_page_state(member) mod_page_state(member, 0UL - 1) #define add_page_state(member,delta) mod_page_state(member, (delta)) #define sub_page_state(member,delta) mod_page_state(member, 0UL - (delta)) -#define mod_page_state_zone(zone, member, delta) \ - do { \ - unsigned long flags; \ - local_irq_save(flags); \ - if (is_highmem(zone)) \ - __get_cpu_var(page_states).member##_high += (delta);\ - else if (is_normal(zone)) \ - __get_cpu_var(page_states).member##_normal += (delta);\ - else \ - __get_cpu_var(page_states).member##_dma += (delta);\ - local_irq_restore(flags); \ +#define mod_page_state_zone(zone, member, delta) \ + do { \ + unsigned offset; \ + if (is_highmem(zone)) \ + offset = offsetof(struct page_state, member##_high); \ + else if (is_normal(zone)) \ + offset = offsetof(struct page_state, member##_normal); \ + else \ + offset = offsetof(struct page_state, member##_dma); \ + __mod_page_state(offset, (delta)); \ } while (0) /* diff -puN mm/page_alloc.c~uninline-mod_page_state mm/page_alloc.c --- 25/mm/page_alloc.c~uninline-mod_page_state 2005-01-16 14:44:25.731225008 -0800 +++ 25-akpm/mm/page_alloc.c 2005-01-16 14:44:25.737224096 -0800 @@ -986,8 +986,7 @@ static void show_node(struct zone *zone) * The result is unavoidably approximate - it can change * during and after execution of this function. */ -DEFINE_PER_CPU(struct page_state, page_states) = {0}; -EXPORT_PER_CPU_SYMBOL(page_states); +static DEFINE_PER_CPU(struct page_state, page_states) = {0}; atomic_t nr_pagecache = ATOMIC_INIT(0); EXPORT_SYMBOL(nr_pagecache); @@ -1047,6 +1046,19 @@ unsigned long __read_page_state(unsigned return ret; } +void __mod_page_state(unsigned offset, unsigned long delta) +{ + unsigned long flags; + void* ptr; + + local_irq_save(flags); + ptr = &__get_cpu_var(page_states); + *(unsigned long*)(ptr + offset) += delta; + local_irq_restore(flags); +} + +EXPORT_SYMBOL(__mod_page_state); + void __get_zone_counts(unsigned long *active, unsigned long *inactive, unsigned long *free, struct pglist_data *pgdat) { _