git.openpandora.org
/
pandora-kernel.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge branch 'topic/pcm-drain-nonblock' into for-linus
[pandora-kernel.git]
/
mm
/
rmap.c
diff --git
a/mm/rmap.c
b/mm/rmap.c
index
23122af
..
0895b5c
100644
(file)
--- a/
mm/rmap.c
+++ b/
mm/rmap.c
@@
-333,7
+333,9
@@
static int page_mapped_in_vma(struct page *page, struct vm_area_struct *vma)
* repeatedly from either page_referenced_anon or page_referenced_file.
*/
static int page_referenced_one(struct page *page,
* repeatedly from either page_referenced_anon or page_referenced_file.
*/
static int page_referenced_one(struct page *page,
- struct vm_area_struct *vma, unsigned int *mapcount)
+ struct vm_area_struct *vma,
+ unsigned int *mapcount,
+ unsigned long *vm_flags)
{
struct mm_struct *mm = vma->vm_mm;
unsigned long address;
{
struct mm_struct *mm = vma->vm_mm;
unsigned long address;
@@
-356,6
+358,7
@@
static int page_referenced_one(struct page *page,
*/
if (vma->vm_flags & VM_LOCKED) {
*mapcount = 1; /* break early from loop */
*/
if (vma->vm_flags & VM_LOCKED) {
*mapcount = 1; /* break early from loop */
+ *vm_flags |= VM_LOCKED;
goto out_unmap;
}
goto out_unmap;
}
@@
-381,11
+384,14
@@
out_unmap:
(*mapcount)--;
pte_unmap_unlock(pte, ptl);
out:
(*mapcount)--;
pte_unmap_unlock(pte, ptl);
out:
+ if (referenced)
+ *vm_flags |= vma->vm_flags;
return referenced;
}
static int page_referenced_anon(struct page *page,
return referenced;
}
static int page_referenced_anon(struct page *page,
- struct mem_cgroup *mem_cont)
+ struct mem_cgroup *mem_cont,
+ unsigned long *vm_flags)
{
unsigned int mapcount;
struct anon_vma *anon_vma;
{
unsigned int mapcount;
struct anon_vma *anon_vma;
@@
-405,7
+411,8
@@
static int page_referenced_anon(struct page *page,
*/
if (mem_cont && !mm_match_cgroup(vma->vm_mm, mem_cont))
continue;
*/
if (mem_cont && !mm_match_cgroup(vma->vm_mm, mem_cont))
continue;
- referenced += page_referenced_one(page, vma, &mapcount);
+ referenced += page_referenced_one(page, vma,
+ &mapcount, vm_flags);
if (!mapcount)
break;
}
if (!mapcount)
break;
}
@@
-418,6
+425,7
@@
static int page_referenced_anon(struct page *page,
* page_referenced_file - referenced check for object-based rmap
* @page: the page we're checking references on.
* @mem_cont: target memory controller
* page_referenced_file - referenced check for object-based rmap
* @page: the page we're checking references on.
* @mem_cont: target memory controller
+ * @vm_flags: collect encountered vma->vm_flags who actually referenced the page
*
* For an object-based mapped page, find all the places it is mapped and
* check/clear the referenced flag. This is done by following the page->mapping
*
* For an object-based mapped page, find all the places it is mapped and
* check/clear the referenced flag. This is done by following the page->mapping
@@
-427,7
+435,8
@@
static int page_referenced_anon(struct page *page,
* This function is only called from page_referenced for object-based pages.
*/
static int page_referenced_file(struct page *page,
* This function is only called from page_referenced for object-based pages.
*/
static int page_referenced_file(struct page *page,
- struct mem_cgroup *mem_cont)
+ struct mem_cgroup *mem_cont,
+ unsigned long *vm_flags)
{
unsigned int mapcount;
struct address_space *mapping = page->mapping;
{
unsigned int mapcount;
struct address_space *mapping = page->mapping;
@@
-467,7
+476,8
@@
static int page_referenced_file(struct page *page,
*/
if (mem_cont && !mm_match_cgroup(vma->vm_mm, mem_cont))
continue;
*/
if (mem_cont && !mm_match_cgroup(vma->vm_mm, mem_cont))
continue;
- referenced += page_referenced_one(page, vma, &mapcount);
+ referenced += page_referenced_one(page, vma,
+ &mapcount, vm_flags);
if (!mapcount)
break;
}
if (!mapcount)
break;
}
@@
-481,29
+491,35
@@
static int page_referenced_file(struct page *page,
* @page: the page to test
* @is_locked: caller holds lock on the page
* @mem_cont: target memory controller
* @page: the page to test
* @is_locked: caller holds lock on the page
* @mem_cont: target memory controller
+ * @vm_flags: collect encountered vma->vm_flags who actually referenced the page
*
* Quick test_and_clear_referenced for all mappings to a page,
* returns the number of ptes which referenced the page.
*/
*
* Quick test_and_clear_referenced for all mappings to a page,
* returns the number of ptes which referenced the page.
*/
-int page_referenced(struct page *page, int is_locked,
- struct mem_cgroup *mem_cont)
+int page_referenced(struct page *page,
+ int is_locked,
+ struct mem_cgroup *mem_cont,
+ unsigned long *vm_flags)
{
int referenced = 0;
if (TestClearPageReferenced(page))
referenced++;
{
int referenced = 0;
if (TestClearPageReferenced(page))
referenced++;
+ *vm_flags = 0;
if (page_mapped(page) && page->mapping) {
if (PageAnon(page))
if (page_mapped(page) && page->mapping) {
if (PageAnon(page))
- referenced += page_referenced_anon(page, mem_cont);
+ referenced += page_referenced_anon(page, mem_cont,
+ vm_flags);
else if (is_locked)
else if (is_locked)
- referenced += page_referenced_file(page, mem_cont);
+ referenced += page_referenced_file(page, mem_cont,
+ vm_flags);
else if (!trylock_page(page))
referenced++;
else {
if (page->mapping)
else if (!trylock_page(page))
referenced++;
else {
if (page->mapping)
- referenced +=
-
page_referenced_file(page, mem_cont
);
+ referenced +=
page_referenced_file(page,
+
mem_cont, vm_flags
);
unlock_page(page);
}
}
unlock_page(page);
}
}
@@
-688,8
+704,10
@@
void page_add_new_anon_rmap(struct page *page,
*/
void page_add_file_rmap(struct page *page)
{
*/
void page_add_file_rmap(struct page *page)
{
- if (atomic_inc_and_test(&page->_mapcount))
+ if (atomic_inc_and_test(&page->_mapcount))
{
__inc_zone_page_state(page, NR_FILE_MAPPED);
__inc_zone_page_state(page, NR_FILE_MAPPED);
+ mem_cgroup_update_mapped_file_stat(page, 1);
+ }
}
#ifdef CONFIG_DEBUG_VM
}
#ifdef CONFIG_DEBUG_VM
@@
-738,6
+756,7
@@
void page_remove_rmap(struct page *page)
mem_cgroup_uncharge_page(page);
__dec_zone_page_state(page,
PageAnon(page) ? NR_ANON_PAGES : NR_FILE_MAPPED);
mem_cgroup_uncharge_page(page);
__dec_zone_page_state(page,
PageAnon(page) ? NR_ANON_PAGES : NR_FILE_MAPPED);
+ mem_cgroup_update_mapped_file_stat(page, -1);
/*
* It would be tidy to reset the PageAnon mapping here,
* but that might overwrite a racing page_add_anon_rmap
/*
* It would be tidy to reset the PageAnon mapping here,
* but that might overwrite a racing page_add_anon_rmap
@@
-1202,7
+1221,6
@@
int try_to_unmap(struct page *page, int migration)
return ret;
}
return ret;
}
-#ifdef CONFIG_UNEVICTABLE_LRU
/**
* try_to_munlock - try to munlock a page
* @page: the page to be munlocked
/**
* try_to_munlock - try to munlock a page
* @page: the page to be munlocked
@@
-1226,4
+1244,4
@@
int try_to_munlock(struct page *page)
else
return try_to_unmap_file(page, 1, 0);
}
else
return try_to_unmap_file(page, 1, 0);
}
-#endif
+