Commit daebe5ee authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] factor free memory into max_sane_readahead()

max_sane_readahead() permits the user to readahead up to
half-the-inactive-list's worth of pages.  Which is totally wrong if most of
memory is free.

So make the limit be

	(nr_inactive + nr_free) / 2
parent 42f834c3
...@@ -140,9 +140,10 @@ static int meminfo_read_proc(char *page, char **start, off_t off, ...@@ -140,9 +140,10 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
struct page_state ps; struct page_state ps;
unsigned long inactive; unsigned long inactive;
unsigned long active; unsigned long active;
unsigned long free;
get_page_state(&ps); get_page_state(&ps);
get_zone_counts(&active, &inactive); get_zone_counts(&active, &inactive, &free);
/* /*
* display in kilobytes. * display in kilobytes.
......
...@@ -193,7 +193,8 @@ typedef struct pglist_data { ...@@ -193,7 +193,8 @@ typedef struct pglist_data {
extern int numnodes; extern int numnodes;
extern struct pglist_data *pgdat_list; extern struct pglist_data *pgdat_list;
void get_zone_counts(unsigned long *active, unsigned long *inactive); void get_zone_counts(unsigned long *active, unsigned long *inactive,
unsigned long *free);
void build_all_zonelists(void); void build_all_zonelists(void);
void wakeup_kswapd(struct zone *zone); void wakeup_kswapd(struct zone *zone);
......
...@@ -776,15 +776,18 @@ void get_full_page_state(struct page_state *ret) ...@@ -776,15 +776,18 @@ void get_full_page_state(struct page_state *ret)
__get_page_state(ret, sizeof(*ret) / sizeof(unsigned long)); __get_page_state(ret, sizeof(*ret) / sizeof(unsigned long));
} }
void get_zone_counts(unsigned long *active, unsigned long *inactive) void get_zone_counts(unsigned long *active,
unsigned long *inactive, unsigned long *free)
{ {
struct zone *zone; struct zone *zone;
*active = 0; *active = 0;
*inactive = 0; *inactive = 0;
*free = 0;
for_each_zone(zone) { for_each_zone(zone) {
*active += zone->nr_active; *active += zone->nr_active;
*inactive += zone->nr_inactive; *inactive += zone->nr_inactive;
*free += zone->free_pages;
} }
} }
...@@ -838,6 +841,7 @@ void show_free_areas(void) ...@@ -838,6 +841,7 @@ void show_free_areas(void)
int cpu, temperature; int cpu, temperature;
unsigned long active; unsigned long active;
unsigned long inactive; unsigned long inactive;
unsigned long free;
struct zone *zone; struct zone *zone;
for_each_zone(zone) { for_each_zone(zone) {
...@@ -863,7 +867,7 @@ void show_free_areas(void) ...@@ -863,7 +867,7 @@ void show_free_areas(void)
} }
get_page_state(&ps); get_page_state(&ps);
get_zone_counts(&active, &inactive); get_zone_counts(&active, &inactive, &free);
printk("\nFree pages: %11ukB (%ukB HighMem)\n", printk("\nFree pages: %11ukB (%ukB HighMem)\n",
K(nr_free_pages()), K(nr_free_pages()),
......
...@@ -477,7 +477,8 @@ unsigned long max_sane_readahead(unsigned long nr) ...@@ -477,7 +477,8 @@ unsigned long max_sane_readahead(unsigned long nr)
{ {
unsigned long active; unsigned long active;
unsigned long inactive; unsigned long inactive;
unsigned long free;
get_zone_counts(&active, &inactive); get_zone_counts(&active, &inactive, &free);
return min(nr, inactive / 2); return min(nr, (inactive + free) / 2);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment