* [PATCH 2/4] SwapMig: add_to_swap() avoid atomic allocations
2005-11-18 1:02 [PATCH 1/4] SwapMig: [resend] CONFIG_MIGRATION fixes Christoph Lameter
@ 2005-11-18 1:03 ` Christoph Lameter
2005-11-18 1:03 ` [PATCH 3/4] SwapMig: Drop unused pages immediately Christoph Lameter
2005-11-18 1:03 ` [PATCH 4/4] SwapMig: Extend parameters for migrate_pages() Christoph Lameter
2 siblings, 0 replies; 4+ messages in thread
From: Christoph Lameter @ 2005-11-18 1:03 UTC (permalink / raw)
To: akpm; +Cc: linux-kernel, Christoph Lameter, lhms-devel
Add gfp_mask to add_to_swap
add_to_swap does allocations with GFP_ATOMIC in order not to
interfere with swapping. During migration we may have
use add_to_swap extensively which may lead to out of memory
errors.
This patch makes add_to_swap take a parameter that specifies
the gfp mask. The page migration code can then make add_to_swap
use GFP_KERNEL.
Signed-off-by: Hirokazu Takahashi <taka@valinux.co.jp>
Signed-off-by: Dave Hansen <haveblue@us.ibm.com>
Signed-off-by: Christoph Lameter <clameter@sgi.com>
Index: linux-2.6.15-rc1-mm1/include/linux/swap.h
===================================================================
--- linux-2.6.15-rc1-mm1.orig/include/linux/swap.h 2005-11-17 16:55:05.000000000 -0800
+++ linux-2.6.15-rc1-mm1/include/linux/swap.h 2005-11-17 16:57:30.000000000 -0800
@@ -231,7 +231,7 @@ extern int rw_swap_page_sync(int, swp_en
extern struct address_space swapper_space;
#define total_swapcache_pages swapper_space.nrpages
extern void show_swap_cache_info(void);
-extern int add_to_swap(struct page *);
+extern int add_to_swap(struct page *, gfp_t);
extern void __delete_from_swap_cache(struct page *);
extern void delete_from_swap_cache(struct page *);
extern int move_to_swap_cache(struct page *, swp_entry_t);
Index: linux-2.6.15-rc1-mm1/mm/swap_state.c
===================================================================
--- linux-2.6.15-rc1-mm1.orig/mm/swap_state.c 2005-11-17 15:17:32.000000000 -0800
+++ linux-2.6.15-rc1-mm1/mm/swap_state.c 2005-11-17 16:57:30.000000000 -0800
@@ -142,7 +142,7 @@ void __delete_from_swap_cache(struct pag
* Allocate swap space for the page and add the page to the
* swap cache. Caller needs to hold the page lock.
*/
-int add_to_swap(struct page * page)
+int add_to_swap(struct page * page, gfp_t gfp_mask)
{
swp_entry_t entry;
int err;
@@ -170,7 +170,7 @@ int add_to_swap(struct page * page)
* Add it to the swap cache and mark it dirty
*/
err = __add_to_swap_cache(page, entry,
- GFP_ATOMIC|__GFP_NOMEMALLOC|__GFP_NOWARN);
+ gfp_mask|__GFP_NOMEMALLOC|__GFP_NOWARN);
switch (err) {
case 0: /* Success */
Index: linux-2.6.15-rc1-mm1/mm/vmscan.c
===================================================================
--- linux-2.6.15-rc1-mm1.orig/mm/vmscan.c 2005-11-17 16:55:49.000000000 -0800
+++ linux-2.6.15-rc1-mm1/mm/vmscan.c 2005-11-17 16:57:30.000000000 -0800
@@ -455,7 +455,7 @@ static int shrink_list(struct list_head
if (PageAnon(page) && !PageSwapCache(page)) {
if (!sc->may_swap)
goto keep_locked;
- if (!add_to_swap(page))
+ if (!add_to_swap(page, GFP_ATOMIC))
goto activate_locked;
}
#endif /* CONFIG_SWAP */
@@ -726,7 +726,7 @@ redo:
}
if (PageAnon(page) && !PageSwapCache(page)) {
- if (!add_to_swap(page)) {
+ if (!add_to_swap(page, GFP_KERNEL)) {
unlock_page(page);
list_move(&page->lru, &failed);
nr_failed++;
^ permalink raw reply [flat|nested] 4+ messages in thread* [PATCH 4/4] SwapMig: Extend parameters for migrate_pages()
2005-11-18 1:02 [PATCH 1/4] SwapMig: [resend] CONFIG_MIGRATION fixes Christoph Lameter
2005-11-18 1:03 ` [PATCH 2/4] SwapMig: add_to_swap() avoid atomic allocations Christoph Lameter
2005-11-18 1:03 ` [PATCH 3/4] SwapMig: Drop unused pages immediately Christoph Lameter
@ 2005-11-18 1:03 ` Christoph Lameter
2 siblings, 0 replies; 4+ messages in thread
From: Christoph Lameter @ 2005-11-18 1:03 UTC (permalink / raw)
To: akpm; +Cc: linux-kernel, Christoph Lameter, lhms-devel
Extend the parameters of migrate_pages() to allow the caller control
over the fate of successfully migrated or impossible to migrate pages.
Swap migration and direct migration will have the same interface after this
patch so that patches can be independently applied to the policy layer
and the core migration code.
Signed-off-by: Christoph Lameter <clameter@sgi.com>
Index: linux-2.6.15-rc1-mm1/include/linux/swap.h
===================================================================
--- linux-2.6.15-rc1-mm1.orig/include/linux/swap.h 2005-11-17 16:57:30.000000000 -0800
+++ linux-2.6.15-rc1-mm1/include/linux/swap.h 2005-11-17 16:58:18.000000000 -0800
@@ -179,7 +179,8 @@ extern int vm_swappiness;
#ifdef CONFIG_MIGRATION
extern int isolate_lru_page(struct page *p);
extern int putback_lru_pages(struct list_head *l);
-extern int migrate_pages(struct list_head *l, struct list_head *t);
+extern int migrate_pages(struct list_head *l, struct list_head *t,
+ struct list_head *moved, struct list_head *failed);
#endif
#ifdef CONFIG_MMU
Index: linux-2.6.15-rc1-mm1/mm/vmscan.c
===================================================================
--- linux-2.6.15-rc1-mm1.orig/mm/vmscan.c 2005-11-17 16:57:35.000000000 -0800
+++ linux-2.6.15-rc1-mm1/mm/vmscan.c 2005-11-17 16:57:46.000000000 -0800
@@ -681,10 +681,10 @@ retry:
* list. The direct migration patchset
* extends this function to avoid the use of swap.
*/
-int migrate_pages(struct list_head *l, struct list_head *t)
+int migrate_pages(struct list_head *from, struct list_head *to,
+ struct list_head *moved, struct list_head *failed)
{
int retry;
- LIST_HEAD(failed);
int nr_failed = 0;
int pass = 0;
struct page *page;
@@ -697,12 +697,12 @@ int migrate_pages(struct list_head *l, s
redo:
retry = 0;
- list_for_each_entry_safe(page, page2, l, lru) {
+ list_for_each_entry_safe(page, page2, from, lru) {
cond_resched();
if (page_count(page) == 1) {
/* page was freed from under us. So we are done. */
- move_to_lru(page);
+ list_move(&page->lru, moved);
continue;
}
/*
@@ -733,7 +733,7 @@ redo:
if (PageAnon(page) && !PageSwapCache(page)) {
if (!add_to_swap(page, GFP_KERNEL)) {
unlock_page(page);
- list_move(&page->lru, &failed);
+ list_move(&page->lru, failed);
nr_failed++;
continue;
}
@@ -743,8 +743,10 @@ redo:
* Page is properly locked and writeback is complete.
* Try to migrate the page.
*/
- if (!swap_page(page))
+ if (!swap_page(page)) {
+ list_move(&page->lru, moved);
continue;
+ }
retry_later:
retry++;
}
@@ -754,9 +756,6 @@ retry_later:
if (!swapwrite)
current->flags &= ~PF_SWAPWRITE;
- if (!list_empty(&failed))
- list_splice(&failed, l);
-
return nr_failed + retry;
}
Index: linux-2.6.15-rc1-mm1/mm/mempolicy.c
===================================================================
--- linux-2.6.15-rc1-mm1.orig/mm/mempolicy.c 2005-11-17 16:54:24.000000000 -0800
+++ linux-2.6.15-rc1-mm1/mm/mempolicy.c 2005-11-17 16:57:46.000000000 -0800
@@ -438,6 +438,19 @@ static int contextualize_policy(int mode
return mpol_check_policy(mode, nodes);
}
+static int swap_pages(struct list_head *pagelist)
+{
+ LIST_HEAD(moved);
+ LIST_HEAD(failed);
+ int n;
+
+ n = migrate_pages(pagelist, NULL, &moved, &failed);
+ putback_lru_pages(&failed);
+ putback_lru_pages(&moved);
+
+ return n;
+}
+
long do_mbind(unsigned long start, unsigned long len,
unsigned long mode, nodemask_t *nmask, unsigned long flags)
{
@@ -490,10 +503,13 @@ long do_mbind(unsigned long start, unsig
(flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) ? &pagelist : NULL);
err = PTR_ERR(vma);
if (!IS_ERR(vma)) {
+ int nr_failed = 0;
+
err = mbind_range(vma, start, end, new);
if (!list_empty(&pagelist))
- migrate_pages(&pagelist, NULL);
- if (!err && !list_empty(&pagelist) && (flags & MPOL_MF_STRICT))
+ nr_failed = swap_pages(&pagelist);
+
+ if (!err && nr_failed && (flags & MPOL_MF_STRICT))
err = -EIO;
}
if (!list_empty(&pagelist))
@@ -644,11 +660,12 @@ int do_migrate_pages(struct mm_struct *m
down_read(&mm->mmap_sem);
check_range(mm, mm->mmap->vm_start, TASK_SIZE, &nodes,
flags | MPOL_MF_DISCONTIG_OK, &pagelist);
+
if (!list_empty(&pagelist)) {
- migrate_pages(&pagelist, NULL);
- if (!list_empty(&pagelist))
- count = putback_lru_pages(&pagelist);
+ count = swap_pages(&pagelist);
+ putback_lru_pages(&pagelist);
}
+
up_read(&mm->mmap_sem);
return count;
}
^ permalink raw reply [flat|nested] 4+ messages in thread