* [patch 17/18] move nr_active and nr_inactive into per-CPU page accounting
@ 2002-05-26 20:47 Andrew Morton
0 siblings, 0 replies; only message in thread
From: Andrew Morton @ 2002-05-26 20:47 UTC (permalink / raw)
To: Linus Torvalds; +Cc: lkml
It might reduce pagemap_lru_lock hold times a little, and is more
consistent. I think all global page accounting is now inside
page_states[].
--- 2.5.18/include/linux/page-flags.h~page-accounting Sun May 26 12:38:12 2002
+++ 2.5.18-akpm/include/linux/page-flags.h Sun May 26 12:38:12 2002
@@ -73,6 +73,8 @@ extern struct page_state {
unsigned long nr_dirty;
unsigned long nr_writeback;
unsigned long nr_pagecache;
+ unsigned long nr_active; /* on active_list LRU */
+ unsigned long nr_inactive; /* on inactive_list LRU */
} ____cacheline_aligned_in_smp page_states[NR_CPUS];
extern void get_page_state(struct page_state *ret);
--- 2.5.18/include/linux/swap.h~page-accounting Sun May 26 12:38:12 2002
+++ 2.5.18-akpm/include/linux/swap.h Sun May 26 12:38:12 2002
@@ -102,8 +102,6 @@ extern unsigned long totalhigh_pages;
extern unsigned int nr_free_pages(void);
extern unsigned int nr_free_buffer_pages(void);
extern unsigned int nr_free_pagecache_pages(void);
-extern int nr_active_pages;
-extern int nr_inactive_pages;
extern void __remove_inode_page(struct page *);
/* Incomplete types for prototype declarations: */
@@ -191,27 +189,27 @@ do { \
DEBUG_LRU_PAGE(page); \
SetPageActive(page); \
list_add(&(page)->lru, &active_list); \
- nr_active_pages++; \
+ inc_page_state(nr_active); \
} while (0)
#define add_page_to_inactive_list(page) \
do { \
DEBUG_LRU_PAGE(page); \
list_add(&(page)->lru, &inactive_list); \
- nr_inactive_pages++; \
+ inc_page_state(nr_inactive); \
} while (0)
#define del_page_from_active_list(page) \
do { \
list_del(&(page)->lru); \
ClearPageActive(page); \
- nr_active_pages--; \
+ dec_page_state(nr_active); \
} while (0)
#define del_page_from_inactive_list(page) \
do { \
list_del(&(page)->lru); \
- nr_inactive_pages--; \
+ dec_page_state(nr_inactive); \
} while (0)
extern spinlock_t swaplock;
--- 2.5.18/fs/proc/proc_misc.c~page-accounting Sun May 26 12:38:12 2002
+++ 2.5.18-akpm/fs/proc/proc_misc.c Sun May 26 12:38:12 2002
@@ -149,8 +149,8 @@ static int meminfo_read_proc(char *page,
"MemShared: %8lu kB\n"
"Cached: %8lu kB\n"
"SwapCached: %8lu kB\n"
- "Active: %8u kB\n"
- "Inactive: %8u kB\n"
+ "Active: %8lu kB\n"
+ "Inactive: %8lu kB\n"
"HighTotal: %8lu kB\n"
"HighFree: %8lu kB\n"
"LowTotal: %8lu kB\n"
@@ -164,8 +164,8 @@ static int meminfo_read_proc(char *page,
K(i.sharedram),
K(ps.nr_pagecache-swapper_space.nrpages),
K(swapper_space.nrpages),
- K(nr_active_pages),
- K(nr_inactive_pages),
+ K(ps.nr_active),
+ K(ps.nr_inactive),
K(i.totalhigh),
K(i.freehigh),
K(i.totalram-i.totalhigh),
--- 2.5.18/mm/page_alloc.c~page-accounting Sun May 26 12:38:12 2002
+++ 2.5.18-akpm/mm/page_alloc.c Sun May 26 12:38:12 2002
@@ -27,8 +27,6 @@
unsigned long totalram_pages;
unsigned long totalhigh_pages;
int nr_swap_pages;
-int nr_active_pages;
-int nr_inactive_pages;
struct list_head inactive_list;
struct list_head active_list;
pg_data_t *pgdat_list;
@@ -528,7 +526,7 @@ void free_pages(unsigned long addr, unsi
/*
* Total amount of free (allocatable) RAM:
*/
-unsigned int nr_free_pages (void)
+unsigned int nr_free_pages(void)
{
unsigned int sum;
zone_t *zone;
@@ -608,10 +606,7 @@ void get_page_state(struct page_state *r
{
int pcpu;
- ret->nr_dirty = 0;
- ret->nr_writeback = 0;
- ret->nr_pagecache = 0;
-
+ memset(ret, 0, sizeof(*ret));
for (pcpu = 0; pcpu < smp_num_cpus; pcpu++) {
struct page_state *ps;
@@ -619,6 +614,8 @@ void get_page_state(struct page_state *r
ret->nr_dirty += ps->nr_dirty;
ret->nr_writeback += ps->nr_writeback;
ret->nr_pagecache += ps->nr_pagecache;
+ ret->nr_active += ps->nr_active;
+ ret->nr_inactive += ps->nr_inactive;
}
}
@@ -658,6 +655,9 @@ void show_free_areas_core(pg_data_t *pgd
unsigned int order;
unsigned type;
pg_data_t *tmpdat = pgdat;
+ struct page_state ps;
+
+ get_page_state(&ps);
printk("Free pages: %6dkB (%6dkB HighMem)\n",
K(nr_free_pages()),
@@ -678,10 +678,12 @@ void show_free_areas_core(pg_data_t *pgd
tmpdat = tmpdat->node_next;
}
- printk("( Active: %d, inactive: %d, free: %d )\n",
- nr_active_pages,
- nr_inactive_pages,
- nr_free_pages());
+ printk("( Active:%lu inactive:%lu dirty:%lu writeback:%lu free:%u )\n",
+ ps.nr_active,
+ ps.nr_inactive,
+ ps.nr_dirty,
+ ps.nr_writeback,
+ nr_free_pages());
for (type = 0; type < MAX_NR_ZONES; type++) {
struct list_head *head, *curr;
--- 2.5.18/mm/vmscan.c~page-accounting Sun May 26 12:38:12 2002
+++ 2.5.18-akpm/mm/vmscan.c Sun May 26 12:38:12 2002
@@ -380,16 +380,17 @@ empty:
return 0;
}
-static int FASTCALL(shrink_cache(int nr_pages, zone_t * classzone, unsigned int gfp_mask, int priority));
-static int shrink_cache(int nr_pages, zone_t * classzone, unsigned int gfp_mask, int priority)
+static int
+shrink_cache(int nr_pages, zone_t *classzone,
+ unsigned int gfp_mask, int priority, int max_scan)
{
struct list_head * entry;
struct address_space *mapping;
- int max_scan = nr_inactive_pages / priority;
int max_mapped = nr_pages << (9 - priority);
spin_lock(&pagemap_lru_lock);
- while (--max_scan >= 0 && (entry = inactive_list.prev) != &inactive_list) {
+ while (--max_scan >= 0 &&
+ (entry = inactive_list.prev) != &inactive_list) {
struct page * page;
if (need_resched()) {
@@ -619,17 +620,25 @@ static int shrink_caches(zone_t * classz
{
int chunk_size = nr_pages;
unsigned long ratio;
+ struct page_state ps;
+ int max_scan;
nr_pages -= kmem_cache_reap(gfp_mask);
if (nr_pages <= 0)
return 0;
nr_pages = chunk_size;
- /* try to keep the active list 2/3 of the size of the cache */
- ratio = (unsigned long) nr_pages * nr_active_pages / ((nr_inactive_pages + 1) * 2);
- refill_inactive(ratio);
- nr_pages = shrink_cache(nr_pages, classzone, gfp_mask, priority);
+ /*
+ * Try to keep the active list 2/3 of the size of the cache
+ */
+ get_page_state(&ps);
+ ratio = (unsigned long)nr_pages * ps.nr_active /
+ ((ps.nr_inactive | 1) * 2);
+ refill_inactive(ratio);
+ max_scan = ps.nr_inactive / priority;
+ nr_pages = shrink_cache(nr_pages, classzone,
+ gfp_mask, priority, max_scan);
if (nr_pages <= 0)
return 0;
--- 2.5.18/mm/filemap.c~page-accounting Sun May 26 12:38:12 2002
+++ 2.5.18-akpm/mm/filemap.c Sun May 26 12:38:12 2002
@@ -1415,16 +1415,19 @@ asmlinkage ssize_t sys_sendfile64(int ou
return ret;
}
-static ssize_t do_readahead(struct file *file, unsigned long index, unsigned long nr)
+static ssize_t
+do_readahead(struct file *file, unsigned long index, unsigned long nr)
{
struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
unsigned long max;
+ struct page_state ps;
if (!mapping || !mapping->a_ops || !mapping->a_ops->readpage)
return -EINVAL;
/* Limit it to a sane percentage of the inactive list.. */
- max = nr_inactive_pages / 2;
+ get_page_state(&ps);
+ max = ps.nr_inactive / 2;
if (nr > max)
nr = max;
-
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2002-05-26 20:51 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-05-26 20:47 [patch 17/18] move nr_active and nr_inactive into per-CPU page accounting Andrew Morton
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.