Skip to content

Commit

Permalink
Revert "mm: batch activate_page() to reduce lock contention"
Browse files Browse the repository at this point in the history
This reverts commit 744ed14.

Chris Mason ended up chasing down some page allocation errors and pages
stuck waiting on the IO scheduler, and was able to narrow it down to two
commits: commit 744ed14 ("mm: batch activate_page() to reduce lock
contention") and d8505de ("mm: simplify code of swap.c").

This reverts the first of them.

Reported-and-debugged-by: Chris Mason <chris.mason@oracle.com>
Cc: Mel Gorman <mel@csn.ul.ie>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Jens Axboe <jaxboe@fusionio.com>
Cc: linux-mm <linux-mm@kvack.org>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Shaohua Li <shaohua.li@intel.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
torvalds committed Jan 17, 2011
1 parent 9e8a462 commit 7a60857
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 92 deletions.
9 changes: 0 additions & 9 deletions mm/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,6 @@ static inline void __put_page(struct page *page)

extern unsigned long highest_memmap_pfn;

#ifdef CONFIG_SMP
extern int putback_active_lru_page(struct zone *zone, struct page *page);
#else
static inline int putback_active_lru_page(struct zone *zone, struct page *page)
{
return 0;
}
#endif

/*
* in mm/vmscan.c:
*/
Expand Down
90 changes: 11 additions & 79 deletions mm/swap.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,94 +271,27 @@ static void update_page_reclaim_stat(struct zone *zone, struct page *page,
}

/*
* A page will go to active list either by activate_page or putback_lru_page.
* In the activate_page case, the page hasn't active bit set. The page might
* not in LRU list because it's isolated before it gets a chance to be moved to
* active list. The window is small because pagevec just stores several pages.
* For such case, we do nothing for such page.
* In the putback_lru_page case, the page isn't in lru list but has active
* bit set
* FIXME: speed this up?
*/
static void __activate_page(struct page *page, void *arg)
void activate_page(struct page *page)
{
struct zone *zone = page_zone(page);
int file = page_is_file_cache(page);
int lru = page_lru_base_type(page);
bool putback = !PageLRU(page);

/* The page is isolated before it's moved to active list */
if (!PageLRU(page) && !PageActive(page))
return;
if ((PageLRU(page) && PageActive(page)) || PageUnevictable(page))
return;

if (!putback)
del_page_from_lru_list(zone, page, lru);
else
SetPageLRU(page);

SetPageActive(page);
lru += LRU_ACTIVE;
add_page_to_lru_list(zone, page, lru);

if (putback)
return;
__count_vm_event(PGACTIVATE);
update_page_reclaim_stat(zone, page, file, 1);
}

#ifdef CONFIG_SMP
static DEFINE_PER_CPU(struct pagevec, activate_page_pvecs);

static void activate_page_drain(int cpu)
{
struct pagevec *pvec = &per_cpu(activate_page_pvecs, cpu);

if (pagevec_count(pvec))
pagevec_lru_move_fn(pvec, __activate_page, NULL);
}

void activate_page(struct page *page)
{
spin_lock_irq(&zone->lru_lock);
if (PageLRU(page) && !PageActive(page) && !PageUnevictable(page)) {
struct pagevec *pvec = &get_cpu_var(activate_page_pvecs);

page_cache_get(page);
if (!pagevec_add(pvec, page))
pagevec_lru_move_fn(pvec, __activate_page, NULL);
put_cpu_var(activate_page_pvecs);
}
}
int file = page_is_file_cache(page);
int lru = page_lru_base_type(page);
del_page_from_lru_list(zone, page, lru);

/* Caller should hold zone->lru_lock */
int putback_active_lru_page(struct zone *zone, struct page *page)
{
struct pagevec *pvec = &get_cpu_var(activate_page_pvecs);
SetPageActive(page);
lru += LRU_ACTIVE;
add_page_to_lru_list(zone, page, lru);
__count_vm_event(PGACTIVATE);

if (!pagevec_add(pvec, page)) {
spin_unlock_irq(&zone->lru_lock);
pagevec_lru_move_fn(pvec, __activate_page, NULL);
spin_lock_irq(&zone->lru_lock);
update_page_reclaim_stat(zone, page, file, 1);
}
put_cpu_var(activate_page_pvecs);
return 1;
}

#else
static inline void activate_page_drain(int cpu)
{
}

void activate_page(struct page *page)
{
struct zone *zone = page_zone(page);

spin_lock_irq(&zone->lru_lock);
if (PageLRU(page) && !PageActive(page) && !PageUnevictable(page))
__activate_page(page, NULL);
spin_unlock_irq(&zone->lru_lock);
}
#endif

/*
* Mark a page as having seen activity.
Expand Down Expand Up @@ -457,7 +390,6 @@ static void drain_cpu_pagevecs(int cpu)
pagevec_move_tail(pvec);
local_irq_restore(flags);
}
activate_page_drain(cpu);
}

void lru_add_drain(void)
Expand Down
6 changes: 2 additions & 4 deletions mm/vmscan.c
Original file line number Diff line number Diff line change
Expand Up @@ -1271,16 +1271,14 @@ putback_lru_pages(struct zone *zone, struct scan_control *sc,
spin_lock_irq(&zone->lru_lock);
continue;
}
SetPageLRU(page);
lru = page_lru(page);
add_page_to_lru_list(zone, page, lru);
if (is_active_lru(lru)) {
int file = is_file_lru(lru);
int numpages = hpage_nr_pages(page);
reclaim_stat->recent_rotated[file] += numpages;
if (putback_active_lru_page(zone, page))
continue;
}
SetPageLRU(page);
add_page_to_lru_list(zone, page, lru);
if (!pagevec_add(&pvec, page)) {
spin_unlock_irq(&zone->lru_lock);
__pagevec_release(&pvec);
Expand Down

0 comments on commit 7a60857

Please sign in to comment.