Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 284415
b: refs/heads/master
c: 3f79768
h: refs/heads/master
i:
  284413: 3c7a305
  284411: ca987fa
  284407: 2f257e4
  284399: f1039c9
  284383: 1b86b57
  284351: 80a39ad
  284287: 9585608
  284159: d8b34dc
v: v3
  • Loading branch information
Hugh Dickins authored and Linus Torvalds committed Jan 13, 2012
1 parent 8a6d901 commit c7a42c4
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 53 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f626012db08b9ea71363327d81fe60c2782eea9f
refs/heads/master: 3f79768f239746d19accd88da96263ef35d6a219
96 changes: 44 additions & 52 deletions trunk/mm/vmscan.c
Original file line number Diff line number Diff line change
Expand Up @@ -1284,32 +1284,6 @@ static unsigned long isolate_lru_pages(unsigned long nr_to_scan,
return nr_taken;
}

/*
* clear_active_flags() is a helper for shrink_active_list(), clearing
* any active bits from the pages in the list.
*/
static unsigned long clear_active_flags(struct list_head *page_list,
unsigned int *count)
{
int nr_active = 0;
int lru;
struct page *page;

list_for_each_entry(page, page_list, lru) {
int numpages = hpage_nr_pages(page);
lru = page_lru_base_type(page);
if (PageActive(page)) {
lru += LRU_ACTIVE;
ClearPageActive(page);
nr_active += numpages;
}
if (count)
count[lru] += numpages;
}

return nr_active;
}

/**
* isolate_lru_page - tries to isolate a page from its LRU list
* @page: page to isolate from its LRU list
Expand Down Expand Up @@ -1383,26 +1357,21 @@ static int too_many_isolated(struct zone *zone, int file,
return isolated > inactive;
}

/*
* TODO: Try merging with migrations version of putback_lru_pages
*/
static noinline_for_stack void
putback_lru_pages(struct mem_cgroup_zone *mz, struct scan_control *sc,
unsigned long nr_anon, unsigned long nr_file,
struct list_head *page_list)
putback_inactive_pages(struct mem_cgroup_zone *mz,
struct list_head *page_list)
{
struct page *page;
LIST_HEAD(pages_to_free);
struct zone *zone = mz->zone;
struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(mz);
struct zone *zone = mz->zone;
LIST_HEAD(pages_to_free);

/*
* Put back any unfreeable pages.
*/
spin_lock(&zone->lru_lock);
while (!list_empty(page_list)) {
struct page *page = lru_to_page(page_list);
int lru;
page = lru_to_page(page_list);

VM_BUG_ON(PageLRU(page));
list_del(&page->lru);
if (unlikely(!page_evictable(page, NULL))) {
Expand Down Expand Up @@ -1432,26 +1401,40 @@ putback_lru_pages(struct mem_cgroup_zone *mz, struct scan_control *sc,
list_add(&page->lru, &pages_to_free);
}
}
__mod_zone_page_state(zone, NR_ISOLATED_ANON, -nr_anon);
__mod_zone_page_state(zone, NR_ISOLATED_FILE, -nr_file);

spin_unlock_irq(&zone->lru_lock);
free_hot_cold_page_list(&pages_to_free, 1);
/*
* To save our caller's stack, now use input list for pages to free.
*/
list_splice(&pages_to_free, page_list);
}

static noinline_for_stack void
update_isolated_counts(struct mem_cgroup_zone *mz,
struct scan_control *sc,
struct list_head *page_list,
unsigned long *nr_anon,
unsigned long *nr_file,
struct list_head *isolated_list)
unsigned long *nr_file)
{
unsigned long nr_active;
struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(mz);
struct zone *zone = mz->zone;
unsigned int count[NR_LRU_LISTS] = { 0, };
struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(mz);
unsigned long nr_active = 0;
struct page *page;
int lru;

/*
* Count pages and clear active flags
*/
list_for_each_entry(page, page_list, lru) {
int numpages = hpage_nr_pages(page);
lru = page_lru_base_type(page);
if (PageActive(page)) {
lru += LRU_ACTIVE;
ClearPageActive(page);
nr_active += numpages;
}
count[lru] += numpages;
}

nr_active = clear_active_flags(isolated_list, count);
__count_vm_events(PGDEACTIVATE, nr_active);

__mod_zone_page_state(zone, NR_ACTIVE_FILE,
Expand All @@ -1465,8 +1448,6 @@ update_isolated_counts(struct mem_cgroup_zone *mz,

*nr_anon = count[LRU_ACTIVE_ANON] + count[LRU_INACTIVE_ANON];
*nr_file = count[LRU_ACTIVE_FILE] + count[LRU_INACTIVE_FILE];
__mod_zone_page_state(zone, NR_ISOLATED_ANON, *nr_anon);
__mod_zone_page_state(zone, NR_ISOLATED_FILE, *nr_file);

reclaim_stat->recent_scanned[0] += *nr_anon;
reclaim_stat->recent_scanned[1] += *nr_file;
Expand Down Expand Up @@ -1571,7 +1552,10 @@ shrink_inactive_list(unsigned long nr_to_scan, struct mem_cgroup_zone *mz,
return 0;
}

update_isolated_counts(mz, sc, &nr_anon, &nr_file, &page_list);
update_isolated_counts(mz, &page_list, &nr_anon, &nr_file);

__mod_zone_page_state(zone, NR_ISOLATED_ANON, nr_anon);
__mod_zone_page_state(zone, NR_ISOLATED_FILE, nr_file);

spin_unlock_irq(&zone->lru_lock);

Expand All @@ -1585,12 +1569,20 @@ shrink_inactive_list(unsigned long nr_to_scan, struct mem_cgroup_zone *mz,
priority, &nr_dirty, &nr_writeback);
}

local_irq_disable();
spin_lock_irq(&zone->lru_lock);

if (current_is_kswapd())
__count_vm_events(KSWAPD_STEAL, nr_reclaimed);
__count_zone_vm_events(PGSTEAL, zone, nr_reclaimed);

putback_lru_pages(mz, sc, nr_anon, nr_file, &page_list);
putback_inactive_pages(mz, &page_list);

__mod_zone_page_state(zone, NR_ISOLATED_ANON, -nr_anon);
__mod_zone_page_state(zone, NR_ISOLATED_FILE, -nr_file);

spin_unlock_irq(&zone->lru_lock);

free_hot_cold_page_list(&page_list, 1);

/*
* If reclaim is isolating dirty pages under writeback, it implies
Expand Down

0 comments on commit c7a42c4

Please sign in to comment.