Compound pages of an arbitrary order may now be on the LRU and
may be reclaimed.
Adjust the counting in vmscan.c to could the number of base
pages.
Also change the active and inactive accounting to do the same.
Signed-off-by: Christoph Lameter <clameter@sgi.com>
---
include/linux/mm_inline.h | 36 +++++++++++++++++++++++++++---------
mm/vmscan.c | 22 ++++++++++++----------
2 files changed, 39 insertions(+), 19 deletions(-)
Index: linux-2.6/include/linux/mm_inline.h
===================================================================
--- linux-2.6.orig/include/linux/mm_inline.h 2007-08-27 19:22:13.000000000 -0700
+++ linux-2.6/include/linux/mm_inline.h 2007-08-27 21:08:27.000000000 -0700
@@ -2,39 +2,57 @@ static inline void
add_page_to_active_list(struct zone *zone, struct page *page)
{
list_add(&page->lru, &zone->active_list);
- __inc_zone_state(zone, NR_ACTIVE);
+ if (!PageHead(page))
+ __inc_zone_state(zone, NR_ACTIVE);
+ else
+ __inc_zone_page_state(page, NR_ACTIVE);
}
static inline void
add_page_to_inactive_list(struct zone *zone, struct page *page)
{
list_add(&page->lru, &zone->inactive_list);
- __inc_zone_state(zone, NR_INACTIVE);
+ if (!PageHead(page))
+ __inc_zone_state(zone, NR_INACTIVE);
+ else
+ __inc_zone_page_state(page, NR_INACTIVE);
}
static inline void
del_page_from_active_list(struct zone *zone, struct page *page)
{
list_del(&page->lru);
- __dec_zone_state(zone, NR_ACTIVE);
+ if (!PageHead(page))
+ __dec_zone_state(zone, NR_ACTIVE);
+ else
+ __dec_zone_page_state(page, NR_ACTIVE);
}
static inline void
del_page_from_inactive_list(struct zone *zone, struct page *page)
{
list_del(&page->lru);
- __dec_zone_state(zone, NR_INACTIVE);
+ if (!PageHead(page))
+ __dec_zone_state(zone, NR_INACTIVE);
+ else
+ __dec_zone_page_state(page, NR_INACTIVE);
}
static inline void
del_page_from_lru(struct zone *zone, struct page *page)
{
+ enum zone_stat_item counter = NR_ACTIVE;
+
list_del(&page->lru);
- if (PageActive(page)) {
+ if (PageActive(page))
__ClearPageActive(page);
- __dec_zone_state(zone, NR_ACTIVE);
- } else {
- __dec_zone_state(zone, NR_INACTIVE);
- }
+ else
+ counter = NR_INACTIVE;
+
+ if (!PageHead(page))
+ __dec_zone_state(zone, counter);
+ else
+ __dec_zone_page_state(page, counter);
}
+
Index: linux-2.6/mm/vmscan.c
===================================================================
--- linux-2.6.orig/mm/vmscan.c 2007-08-27 19:22:13.000000000 -0700
+++ linux-2.6/mm/vmscan.c 2007-08-27 21:08:27.000000000 -0700
@@ -466,14 +466,14 @@ static unsigned long shrink_page_list(st
VM_BUG_ON(PageActive(page));
- sc->nr_scanned++;
+ sc->nr_scanned += compound_pages(page);
if (!sc->may_swap && page_mapped(page))
goto keep_locked;
/* Double the slab pressure for mapped and swapcache pages */
if (page_mapped(page) || PageSwapCache(page))
- sc->nr_scanned++;
+ sc->nr_scanned += compound_pages(page);
may_enter_fs = (sc->gfp_mask & __GFP_FS) ||
(PageSwapCache(page) && (sc->gfp_mask & __GFP_IO));
@@ -590,7 +590,7 @@ static unsigned long shrink_page_list(st
free_it:
unlock_page(page);
- nr_reclaimed++;
+ nr_reclaimed += compound_pages(page);
if (!pagevec_add(&freed_pvec, page))
__pagevec_release_nonlru(&freed_pvec);
continue;
@@ -682,22 +682,23 @@ static unsigned long isolate_lru_pages(u
unsigned long nr_taken = 0;
unsigned long scan;
- for (scan = 0; scan < nr_to_scan && !list_empty(src); scan++) {
+ for (scan = 0; scan < nr_to_scan && !list_empty(src); ) {
struct page *page;
unsigned long pfn;
unsigned long end_pfn;
unsigned long page_pfn;
+ int pages;
int zone_id;
page = lru_to_page(src);
prefetchw_prev_lru_page(page, src, flags);
-
+ pages = compound_pages(page);
VM_BUG_ON(!PageLRU(page));
switch (__isolate_lru_page(page, mode)) {
case 0:
list_move(&page->lru, dst);
- nr_taken++;
+ nr_taken += pages;
break;
case -EBUSY:
@@ -743,8 +744,8 @@ static unsigned long isolate_lru_pages(u
switch (__isolate_lru_page(cursor_page, mode)) {
case 0:
list_move(&cursor_page->lru, dst);
- nr_taken++;
- scan++;
+ nr_taken += compound_pages(cursor_page);
+ scan += compound_pages(cursor_page);
break;
case -EBUSY:
@@ -754,6 +755,7 @@ static unsigned long isolate_lru_pages(u
break;
}
}
+ scan += pages;
}
*scanned = scan;
@@ -1010,7 +1012,7 @@ force_reclaim_mapped:
ClearPageActive(page);
list_move(&page->lru, &zone->inactive_list);
- pgmoved++;
+ pgmoved += compound_pages(page);
if (!pagevec_add(&pvec, page)) {
__mod_zone_page_state(zone, NR_INACTIVE, pgmoved);
spin_unlock_irq(&zone->lru_lock);
@@ -1038,7 +1040,7 @@ force_reclaim_mapped:
SetPageLRU(page);
VM_BUG_ON(!PageActive(page));
list_move(&page->lru, &zone->active_list);
- pgmoved++;
+ pgmoved += compound_pages(page);
if (!pagevec_add(&pvec, page)) {
__mod_zone_page_state(zone, NR_ACTIVE, pgmoved);
pgmoved = 0;
--
-
| Linus Torvalds | Linux 2.6.27-rc8 |
| Rafael J. Wysocki | 2.6.26-rc9-git12: Reported regressions from 2.6.25 |
| Jarod Wilson | [PATCH 05/18] lirc driver for i2c-based IR receivers |
| Vladislav Bolkhovitin | Re: Integration of SCST in the mainstream Linux kernel |
git: | |
| Andrew Morton | email address handling |
| Pierre Habouzit | Re: [RFC] Re: Convert 'git blame' to parse_options() |
| Linus Torvalds | Re: What's in git.git (stable), and Announcing GIT 1.4.4.3 |
| Brian Gernhardt | Re: [FIXED PATCH] Make rebase save ORIG_HEAD if changing current branch |
| Leon Dippenaar | New tcp stack attack |
| Marco Peereboom | Re: Real men don't attack straw men |
| Richard Storm | MAXDSIZ 1GB memory limit for process |
| GVG GVG | ssh_exchange_identification: Connection closed by remote host |
| Patrick McHardy | [NET_SCHED 00/04]: External SFQ classifiers/flow classifier |
| Arjan van de Ven | Re: [GIT]: Networking |
| Ingo Oeser | Re: [PATCH]: Third (final?) release of Sun Neptune driver |
| Linus Torvalds | Re: [GIT]: Networking |
