Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 115834
b: refs/heads/master
c: 62695a8
h: refs/heads/master
v: v3
  • Loading branch information
Nick Piggin authored and Linus Torvalds committed Oct 20, 2008
1 parent 5c6872b commit babdefb
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 38 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: 71088785c6bc68fddb450063d57b1bd1c78e0ea1
refs/heads/master: 62695a84eb8f2e718bf4dfb21700afaa7a08e0ea
3 changes: 0 additions & 3 deletions trunk/include/linux/migrate.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
typedef struct page *new_page_t(struct page *, unsigned long private, int **);

#ifdef CONFIG_MIGRATION
extern int isolate_lru_page(struct page *p, struct list_head *pagelist);
extern int putback_lru_pages(struct list_head *l);
extern int migrate_page(struct address_space *,
struct page *, struct page *);
Expand All @@ -21,8 +20,6 @@ extern int migrate_vmas(struct mm_struct *mm,
const nodemask_t *from, const nodemask_t *to,
unsigned long flags);
#else
static inline int isolate_lru_page(struct page *p, struct list_head *list)
{ return -ENOSYS; }
static inline int putback_lru_pages(struct list_head *l) { return 0; }
static inline int migrate_pages(struct list_head *l, new_page_t x,
unsigned long private) { return -ENOSYS; }
Expand Down
2 changes: 2 additions & 0 deletions trunk/mm/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ static inline void __put_page(struct page *page)
atomic_dec(&page->_count);
}

extern int isolate_lru_page(struct page *page);

extern void __free_pages_bootmem(struct page *page, unsigned int order);

/*
Expand Down
3 changes: 2 additions & 1 deletion trunk/mm/memory_hotplug.c
Original file line number Diff line number Diff line change
Expand Up @@ -658,8 +658,9 @@ do_migrate_range(unsigned long start_pfn, unsigned long end_pfn)
* We can skip free pages. And we can only deal with pages on
* LRU.
*/
ret = isolate_lru_page(page, &source);
ret = isolate_lru_page(page);
if (!ret) { /* Success */
list_add_tail(&page->lru, &source);
move_pages--;
} else {
/* Becasue we don't have big zone->lock. we should
Expand Down
9 changes: 7 additions & 2 deletions trunk/mm/mempolicy.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@
#include <asm/tlbflush.h>
#include <asm/uaccess.h>

#include "internal.h"

/* Internal flags */
#define MPOL_MF_DISCONTIG_OK (MPOL_MF_INTERNAL << 0) /* Skip checks for continuous vmas */
#define MPOL_MF_INVERT (MPOL_MF_INTERNAL << 1) /* Invert check for nodemask */
Expand Down Expand Up @@ -762,8 +764,11 @@ static void migrate_page_add(struct page *page, struct list_head *pagelist,
/*
* Avoid migrating a page that is shared with others.
*/
if ((flags & MPOL_MF_MOVE_ALL) || page_mapcount(page) == 1)
isolate_lru_page(page, pagelist);
if ((flags & MPOL_MF_MOVE_ALL) || page_mapcount(page) == 1) {
if (!isolate_lru_page(page)) {
list_add_tail(&page->lru, pagelist);
}
}
}

static struct page *new_node_page(struct page *page, unsigned long node, int **x)
Expand Down
34 changes: 3 additions & 31 deletions trunk/mm/migrate.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,36 +36,6 @@

#define lru_to_page(_head) (list_entry((_head)->prev, struct page, lru))

/*
* Isolate one page from the LRU lists. If successful put it onto
* the indicated list with elevated page count.
*
* Result:
* -EBUSY: page not on LRU list
* 0: page removed from LRU list and added to the specified list.
*/
int isolate_lru_page(struct page *page, struct list_head *pagelist)
{
int ret = -EBUSY;

if (PageLRU(page)) {
struct zone *zone = page_zone(page);

spin_lock_irq(&zone->lru_lock);
if (PageLRU(page) && get_page_unless_zero(page)) {
ret = 0;
ClearPageLRU(page);
if (PageActive(page))
del_page_from_active_list(zone, page);
else
del_page_from_inactive_list(zone, page);
list_add_tail(&page->lru, pagelist);
}
spin_unlock_irq(&zone->lru_lock);
}
return ret;
}

/*
* migrate_prep() needs to be called before we start compiling a list of pages
* to be migrated using isolate_lru_page().
Expand Down Expand Up @@ -914,7 +884,9 @@ static int do_move_pages(struct mm_struct *mm, struct page_to_node *pm,
!migrate_all)
goto put_and_set;

err = isolate_lru_page(page, &pagelist);
err = isolate_lru_page(page);
if (!err)
list_add_tail(&page->lru, &pagelist);
put_and_set:
/*
* Either remove the duplicate refcount from
Expand Down
45 changes: 45 additions & 0 deletions trunk/mm/vmscan.c
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,51 @@ static unsigned long clear_active_flags(struct list_head *page_list)
return nr_active;
}

/**
* isolate_lru_page - tries to isolate a page from its LRU list
* @page: page to isolate from its LRU list
*
* Isolates a @page from an LRU list, clears PageLRU and adjusts the
* vmstat statistic corresponding to whatever LRU list the page was on.
*
* Returns 0 if the page was removed from an LRU list.
* Returns -EBUSY if the page was not on an LRU list.
*
* The returned page will have PageLRU() cleared. If it was found on
* the active list, it will have PageActive set. That flag may need
* to be cleared by the caller before letting the page go.
*
* The vmstat statistic corresponding to the list on which the page was
* found will be decremented.
*
* Restrictions:
* (1) Must be called with an elevated refcount on the page. This is a
* fundamentnal difference from isolate_lru_pages (which is called
* without a stable reference).
* (2) the lru_lock must not be held.
* (3) interrupts must be enabled.
*/
int isolate_lru_page(struct page *page)
{
int ret = -EBUSY;

if (PageLRU(page)) {
struct zone *zone = page_zone(page);

spin_lock_irq(&zone->lru_lock);
if (PageLRU(page) && get_page_unless_zero(page)) {
ret = 0;
ClearPageLRU(page);
if (PageActive(page))
del_page_from_active_list(zone, page);
else
del_page_from_inactive_list(zone, page);
}
spin_unlock_irq(&zone->lru_lock);
}
return ret;
}

/*
* shrink_inactive_list() is a helper for shrink_zone(). It returns the number
* of reclaimed pages
Expand Down

0 comments on commit babdefb

Please sign in to comment.