git://ftp.safe.ca
/
safe
/
jmp
/
linux-2.6
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
mm: add_to_swap_cache() must not sleep
[safe/jmp/linux-2.6]
/
mm
/
migrate.c
diff --git
a/mm/migrate.c
b/mm/migrate.c
index
068655d
..
b535a2c
100644
(file)
--- a/
mm/migrate.c
+++ b/
mm/migrate.c
@@
-67,6
+67,8
@@
int putback_lru_pages(struct list_head *l)
list_for_each_entry_safe(page, page2, l, lru) {
list_del(&page->lru);
list_for_each_entry_safe(page, page2, l, lru) {
list_del(&page->lru);
+ dec_zone_page_state(page, NR_ISOLATED_ANON +
+ !!page_is_file_cache(page));
putback_lru_page(page);
count++;
}
putback_lru_page(page);
count++;
}
@@
-147,7
+149,7
@@
out:
static void remove_file_migration_ptes(struct page *old, struct page *new)
{
struct vm_area_struct *vma;
static void remove_file_migration_ptes(struct page *old, struct page *new)
{
struct vm_area_struct *vma;
- struct address_space *mapping =
page_mapping(new)
;
+ struct address_space *mapping =
new->mapping
;
struct prio_tree_iter iter;
pgoff_t pgoff = new->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
struct prio_tree_iter iter;
pgoff_t pgoff = new->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
@@
-312,7
+314,10
@@
static int migrate_page_move_mapping(struct address_space *mapping,
*/
__dec_zone_page_state(page, NR_FILE_PAGES);
__inc_zone_page_state(newpage, NR_FILE_PAGES);
*/
__dec_zone_page_state(page, NR_FILE_PAGES);
__inc_zone_page_state(newpage, NR_FILE_PAGES);
-
+ if (PageSwapBacked(page)) {
+ __dec_zone_page_state(page, NR_SHMEM);
+ __inc_zone_page_state(newpage, NR_SHMEM);
+ }
spin_unlock_irq(&mapping->tree_lock);
return 0;
spin_unlock_irq(&mapping->tree_lock);
return 0;
@@
-664,13
+669,15
@@
static int unmap_and_move(new_page_t get_new_page, unsigned long private,
* needs to be effective.
*/
try_to_free_buffers(page);
* needs to be effective.
*/
try_to_free_buffers(page);
+ goto rcu_unlock;
}
}
- goto
rcu_unlock
;
+ goto
skip_unmap
;
}
/* Establish migration ptes or remove ptes */
try_to_unmap(page, 1);
}
/* Establish migration ptes or remove ptes */
try_to_unmap(page, 1);
+skip_unmap:
if (!page_mapped(page))
rc = move_to_new_page(newpage, page);
if (!page_mapped(page))
rc = move_to_new_page(newpage, page);
@@
-693,6
+700,8
@@
unlock:
* restored.
*/
list_del(&page->lru);
* restored.
*/
list_del(&page->lru);
+ dec_zone_page_state(page, NR_ISOLATED_ANON +
+ !!page_is_file_cache(page));
putback_lru_page(page);
}
putback_lru_page(page);
}
@@
-737,6
+746,13
@@
int migrate_pages(struct list_head *from,
struct page *page2;
int swapwrite = current->flags & PF_SWAPWRITE;
int rc;
struct page *page2;
int swapwrite = current->flags & PF_SWAPWRITE;
int rc;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ list_for_each_entry(page, from, lru)
+ __inc_zone_page_state(page, NR_ISOLATED_ANON +
+ !!page_is_file_cache(page));
+ local_irq_restore(flags);
if (!swapwrite)
current->flags |= PF_SWAPWRITE;
if (!swapwrite)
current->flags |= PF_SWAPWRITE;
@@
-802,7
+818,7
@@
static struct page *new_page_node(struct page *p, unsigned long private,
*result = &pm->status;
*result = &pm->status;
- return alloc_pages_node(pm->node,
+ return alloc_pages_
exact_
node(pm->node,
GFP_HIGHUSER_MOVABLE | GFP_THISNODE, 0);
}
GFP_HIGHUSER_MOVABLE | GFP_THISNODE, 0);
}
@@
-820,7
+836,6
@@
static int do_move_page_to_node_array(struct mm_struct *mm,
struct page_to_node *pp;
LIST_HEAD(pagelist);
struct page_to_node *pp;
LIST_HEAD(pagelist);
- migrate_prep();
down_read(&mm->mmap_sem);
/*
down_read(&mm->mmap_sem);
/*
@@
-907,6
+922,9
@@
static int do_pages_move(struct mm_struct *mm, struct task_struct *task,
pm = (struct page_to_node *)__get_free_page(GFP_KERNEL);
if (!pm)
goto out;
pm = (struct page_to_node *)__get_free_page(GFP_KERNEL);
if (!pm)
goto out;
+
+ migrate_prep();
+
/*
* Store a chunk of page_to_node array in a page,
* but keep the last one as a marker
/*
* Store a chunk of page_to_node array in a page,
* but keep the last one as a marker