diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/Kconfig | 6 | ||||
-rw-r--r-- | mm/Makefile | 1 | ||||
-rw-r--r-- | mm/filemap.c | 26 | ||||
-rw-r--r-- | mm/filemap_xip.c | 3 | ||||
-rw-r--r-- | mm/fremap.c | 3 | ||||
-rw-r--r-- | mm/hugetlb.c | 73 | ||||
-rw-r--r-- | mm/madvise.c | 4 | ||||
-rw-r--r-- | mm/memcontrol.c | 5 | ||||
-rw-r--r-- | mm/memory.c | 76 | ||||
-rw-r--r-- | mm/mempolicy.c | 1 | ||||
-rw-r--r-- | mm/migrate.c | 4 | ||||
-rw-r--r-- | mm/mlock.c | 2 | ||||
-rw-r--r-- | mm/mm_init.c | 8 | ||||
-rw-r--r-- | mm/mmap.c | 168 | ||||
-rw-r--r-- | mm/mmu_notifier.c | 277 | ||||
-rw-r--r-- | mm/mprotect.c | 3 | ||||
-rw-r--r-- | mm/mremap.c | 6 | ||||
-rw-r--r-- | mm/nommu.c | 21 | ||||
-rw-r--r-- | mm/page_alloc.c | 23 | ||||
-rw-r--r-- | mm/rmap.c | 18 | ||||
-rw-r--r-- | mm/shmem.c | 7 | ||||
-rw-r--r-- | mm/slab.c | 1 | ||||
-rw-r--r-- | mm/slob.c | 1 | ||||
-rw-r--r-- | mm/slub.c | 27 | ||||
-rw-r--r-- | mm/sparse.c | 1 | ||||
-rw-r--r-- | mm/swap.c | 9 | ||||
-rw-r--r-- | mm/swap_state.c | 8 | ||||
-rw-r--r-- | mm/swapfile.c | 6 | ||||
-rw-r--r-- | mm/truncate.c | 6 | ||||
-rw-r--r-- | mm/util.c | 15 | ||||
-rw-r--r-- | mm/vmscan.c | 8 |
31 files changed, 706 insertions, 111 deletions
diff --git a/mm/Kconfig b/mm/Kconfig index efee5d379df4..0bd9c2dbb2a0 100644 --- a/mm/Kconfig +++ b/mm/Kconfig | |||
@@ -77,9 +77,6 @@ config FLAT_NODE_MEM_MAP | |||
77 | def_bool y | 77 | def_bool y |
78 | depends on !SPARSEMEM | 78 | depends on !SPARSEMEM |
79 | 79 | ||
80 | config HAVE_GET_USER_PAGES_FAST | ||
81 | bool | ||
82 | |||
83 | # | 80 | # |
84 | # Both the NUMA code and DISCONTIGMEM use arrays of pg_data_t's | 81 | # Both the NUMA code and DISCONTIGMEM use arrays of pg_data_t's |
85 | # to represent different areas of memory. This variable allows | 82 | # to represent different areas of memory. This variable allows |
@@ -208,3 +205,6 @@ config NR_QUICK | |||
208 | config VIRT_TO_BUS | 205 | config VIRT_TO_BUS |
209 | def_bool y | 206 | def_bool y |
210 | depends on !ARCH_NO_VIRT_TO_BUS | 207 | depends on !ARCH_NO_VIRT_TO_BUS |
208 | |||
209 | config MMU_NOTIFIER | ||
210 | bool | ||
diff --git a/mm/Makefile b/mm/Makefile index 06ca2381fef1..da4ccf015aea 100644 --- a/mm/Makefile +++ b/mm/Makefile | |||
@@ -25,6 +25,7 @@ obj-$(CONFIG_SHMEM) += shmem.o | |||
25 | obj-$(CONFIG_TMPFS_POSIX_ACL) += shmem_acl.o | 25 | obj-$(CONFIG_TMPFS_POSIX_ACL) += shmem_acl.o |
26 | obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o | 26 | obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o |
27 | obj-$(CONFIG_SLOB) += slob.o | 27 | obj-$(CONFIG_SLOB) += slob.o |
28 | obj-$(CONFIG_MMU_NOTIFIER) += mmu_notifier.o | ||
28 | obj-$(CONFIG_SLAB) += slab.o | 29 | obj-$(CONFIG_SLAB) += slab.o |
29 | obj-$(CONFIG_SLUB) += slub.o | 30 | obj-$(CONFIG_SLUB) += slub.o |
30 | obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o | 31 | obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o |
diff --git a/mm/filemap.c b/mm/filemap.c index 5de7633e1dbe..54e968650855 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -558,14 +558,14 @@ EXPORT_SYMBOL(wait_on_page_bit); | |||
558 | * But that's OK - sleepers in wait_on_page_writeback() just go back to sleep. | 558 | * But that's OK - sleepers in wait_on_page_writeback() just go back to sleep. |
559 | * | 559 | * |
560 | * The first mb is necessary to safely close the critical section opened by the | 560 | * The first mb is necessary to safely close the critical section opened by the |
561 | * TestSetPageLocked(), the second mb is necessary to enforce ordering between | 561 | * test_and_set_bit() to lock the page; the second mb is necessary to enforce |
562 | * the clear_bit and the read of the waitqueue (to avoid SMP races with a | 562 | * ordering between the clear_bit and the read of the waitqueue (to avoid SMP |
563 | * parallel wait_on_page_locked()). | 563 | * races with a parallel wait_on_page_locked()). |
564 | */ | 564 | */ |
565 | void unlock_page(struct page *page) | 565 | void unlock_page(struct page *page) |
566 | { | 566 | { |
567 | smp_mb__before_clear_bit(); | 567 | smp_mb__before_clear_bit(); |
568 | if (!TestClearPageLocked(page)) | 568 | if (!test_and_clear_bit(PG_locked, &page->flags)) |
569 | BUG(); | 569 | BUG(); |
570 | smp_mb__after_clear_bit(); | 570 | smp_mb__after_clear_bit(); |
571 | wake_up_page(page, PG_locked); | 571 | wake_up_page(page, PG_locked); |
@@ -931,7 +931,7 @@ grab_cache_page_nowait(struct address_space *mapping, pgoff_t index) | |||
931 | struct page *page = find_get_page(mapping, index); | 931 | struct page *page = find_get_page(mapping, index); |
932 | 932 | ||
933 | if (page) { | 933 | if (page) { |
934 | if (!TestSetPageLocked(page)) | 934 | if (trylock_page(page)) |
935 | return page; | 935 | return page; |
936 | page_cache_release(page); | 936 | page_cache_release(page); |
937 | return NULL; | 937 | return NULL; |
@@ -1023,8 +1023,17 @@ find_page: | |||
1023 | ra, filp, page, | 1023 | ra, filp, page, |
1024 | index, last_index - index); | 1024 | index, last_index - index); |
1025 | } | 1025 | } |
1026 | if (!PageUptodate(page)) | 1026 | if (!PageUptodate(page)) { |
1027 | goto page_not_up_to_date; | 1027 | if (inode->i_blkbits == PAGE_CACHE_SHIFT || |
1028 | !mapping->a_ops->is_partially_uptodate) | ||
1029 | goto page_not_up_to_date; | ||
1030 | if (!trylock_page(page)) | ||
1031 | goto page_not_up_to_date; | ||
1032 | if (!mapping->a_ops->is_partially_uptodate(page, | ||
1033 | desc, offset)) | ||
1034 | goto page_not_up_to_date_locked; | ||
1035 | unlock_page(page); | ||
1036 | } | ||
1028 | page_ok: | 1037 | page_ok: |
1029 | /* | 1038 | /* |
1030 | * i_size must be checked after we know the page is Uptodate. | 1039 | * i_size must be checked after we know the page is Uptodate. |
@@ -1094,6 +1103,7 @@ page_not_up_to_date: | |||
1094 | if (lock_page_killable(page)) | 1103 | if (lock_page_killable(page)) |
1095 | goto readpage_eio; | 1104 | goto readpage_eio; |
1096 | 1105 | ||
1106 | page_not_up_to_date_locked: | ||
1097 | /* Did it get truncated before we got the lock? */ | 1107 | /* Did it get truncated before we got the lock? */ |
1098 | if (!page->mapping) { | 1108 | if (!page->mapping) { |
1099 | unlock_page(page); | 1109 | unlock_page(page); |
@@ -1869,7 +1879,7 @@ void iov_iter_advance(struct iov_iter *i, size_t bytes) | |||
1869 | * The !iov->iov_len check ensures we skip over unlikely | 1879 | * The !iov->iov_len check ensures we skip over unlikely |
1870 | * zero-length segments (without overruning the iovec). | 1880 | * zero-length segments (without overruning the iovec). |
1871 | */ | 1881 | */ |
1872 | while (bytes || unlikely(!iov->iov_len && i->count)) { | 1882 | while (bytes || unlikely(i->count && !iov->iov_len)) { |
1873 | int copy; | 1883 | int copy; |
1874 | 1884 | ||
1875 | copy = min(bytes, iov->iov_len - base); | 1885 | copy = min(bytes, iov->iov_len - base); |
diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c index 98a3f31ccd6a..380ab402d711 100644 --- a/mm/filemap_xip.c +++ b/mm/filemap_xip.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/uio.h> | 14 | #include <linux/uio.h> |
15 | #include <linux/rmap.h> | 15 | #include <linux/rmap.h> |
16 | #include <linux/mmu_notifier.h> | ||
16 | #include <linux/sched.h> | 17 | #include <linux/sched.h> |
17 | #include <asm/tlbflush.h> | 18 | #include <asm/tlbflush.h> |
18 | #include <asm/io.h> | 19 | #include <asm/io.h> |
@@ -188,7 +189,7 @@ __xip_unmap (struct address_space * mapping, | |||
188 | if (pte) { | 189 | if (pte) { |
189 | /* Nuke the page table entry. */ | 190 | /* Nuke the page table entry. */ |
190 | flush_cache_page(vma, address, pte_pfn(*pte)); | 191 | flush_cache_page(vma, address, pte_pfn(*pte)); |
191 | pteval = ptep_clear_flush(vma, address, pte); | 192 | pteval = ptep_clear_flush_notify(vma, address, pte); |
192 | page_remove_rmap(page, vma); | 193 | page_remove_rmap(page, vma); |
193 | dec_mm_counter(mm, file_rss); | 194 | dec_mm_counter(mm, file_rss); |
194 | BUG_ON(pte_dirty(pteval)); | 195 | BUG_ON(pte_dirty(pteval)); |
diff --git a/mm/fremap.c b/mm/fremap.c index 07a9c82ce1a3..7881638e4a12 100644 --- a/mm/fremap.c +++ b/mm/fremap.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/rmap.h> | 15 | #include <linux/rmap.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/syscalls.h> | 17 | #include <linux/syscalls.h> |
18 | #include <linux/mmu_notifier.h> | ||
18 | 19 | ||
19 | #include <asm/mmu_context.h> | 20 | #include <asm/mmu_context.h> |
20 | #include <asm/cacheflush.h> | 21 | #include <asm/cacheflush.h> |
@@ -214,7 +215,9 @@ asmlinkage long sys_remap_file_pages(unsigned long start, unsigned long size, | |||
214 | spin_unlock(&mapping->i_mmap_lock); | 215 | spin_unlock(&mapping->i_mmap_lock); |
215 | } | 216 | } |
216 | 217 | ||
218 | mmu_notifier_invalidate_range_start(mm, start, start + size); | ||
217 | err = populate_range(mm, vma, start, size, pgoff); | 219 | err = populate_range(mm, vma, start, size, pgoff); |
220 | mmu_notifier_invalidate_range_end(mm, start, start + size); | ||
218 | if (!err && !(flags & MAP_NONBLOCK)) { | 221 | if (!err && !(flags & MAP_NONBLOCK)) { |
219 | if (unlikely(has_write_lock)) { | 222 | if (unlikely(has_write_lock)) { |
220 | downgrade_write(&mm->mmap_sem); | 223 | downgrade_write(&mm->mmap_sem); |
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 3be79dc18c5c..67a71191136e 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/mm.h> | 9 | #include <linux/mm.h> |
10 | #include <linux/sysctl.h> | 10 | #include <linux/sysctl.h> |
11 | #include <linux/highmem.h> | 11 | #include <linux/highmem.h> |
12 | #include <linux/mmu_notifier.h> | ||
12 | #include <linux/nodemask.h> | 13 | #include <linux/nodemask.h> |
13 | #include <linux/pagemap.h> | 14 | #include <linux/pagemap.h> |
14 | #include <linux/mempolicy.h> | 15 | #include <linux/mempolicy.h> |
@@ -19,6 +20,7 @@ | |||
19 | 20 | ||
20 | #include <asm/page.h> | 21 | #include <asm/page.h> |
21 | #include <asm/pgtable.h> | 22 | #include <asm/pgtable.h> |
23 | #include <asm/io.h> | ||
22 | 24 | ||
23 | #include <linux/hugetlb.h> | 25 | #include <linux/hugetlb.h> |
24 | #include "internal.h" | 26 | #include "internal.h" |
@@ -563,7 +565,7 @@ static struct page *alloc_fresh_huge_page_node(struct hstate *h, int nid) | |||
563 | huge_page_order(h)); | 565 | huge_page_order(h)); |
564 | if (page) { | 566 | if (page) { |
565 | if (arch_prepare_hugepage(page)) { | 567 | if (arch_prepare_hugepage(page)) { |
566 | __free_pages(page, HUGETLB_PAGE_ORDER); | 568 | __free_pages(page, huge_page_order(h)); |
567 | return NULL; | 569 | return NULL; |
568 | } | 570 | } |
569 | prep_new_huge_page(h, page, nid); | 571 | prep_new_huge_page(h, page, nid); |
@@ -663,6 +665,11 @@ static struct page *alloc_buddy_huge_page(struct hstate *h, | |||
663 | __GFP_REPEAT|__GFP_NOWARN, | 665 | __GFP_REPEAT|__GFP_NOWARN, |
664 | huge_page_order(h)); | 666 | huge_page_order(h)); |
665 | 667 | ||
668 | if (page && arch_prepare_hugepage(page)) { | ||
669 | __free_pages(page, huge_page_order(h)); | ||
670 | return NULL; | ||
671 | } | ||
672 | |||
666 | spin_lock(&hugetlb_lock); | 673 | spin_lock(&hugetlb_lock); |
667 | if (page) { | 674 | if (page) { |
668 | /* | 675 | /* |
@@ -1281,7 +1288,12 @@ module_exit(hugetlb_exit); | |||
1281 | 1288 | ||
1282 | static int __init hugetlb_init(void) | 1289 | static int __init hugetlb_init(void) |
1283 | { | 1290 | { |
1284 | BUILD_BUG_ON(HPAGE_SHIFT == 0); | 1291 | /* Some platform decide whether they support huge pages at boot |
1292 | * time. On these, such as powerpc, HPAGE_SHIFT is set to 0 when | ||
1293 | * there is no such support | ||
1294 | */ | ||
1295 | if (HPAGE_SHIFT == 0) | ||
1296 | return 0; | ||
1285 | 1297 | ||
1286 | if (!size_to_hstate(default_hstate_size)) { | 1298 | if (!size_to_hstate(default_hstate_size)) { |
1287 | default_hstate_size = HPAGE_SIZE; | 1299 | default_hstate_size = HPAGE_SIZE; |
@@ -1672,6 +1684,7 @@ void __unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, | |||
1672 | BUG_ON(start & ~huge_page_mask(h)); | 1684 | BUG_ON(start & ~huge_page_mask(h)); |
1673 | BUG_ON(end & ~huge_page_mask(h)); | 1685 | BUG_ON(end & ~huge_page_mask(h)); |
1674 | 1686 | ||
1687 | mmu_notifier_invalidate_range_start(mm, start, end); | ||
1675 | spin_lock(&mm->page_table_lock); | 1688 | spin_lock(&mm->page_table_lock); |
1676 | for (address = start; address < end; address += sz) { | 1689 | for (address = start; address < end; address += sz) { |
1677 | ptep = huge_pte_offset(mm, address); | 1690 | ptep = huge_pte_offset(mm, address); |
@@ -1713,6 +1726,7 @@ void __unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, | |||
1713 | } | 1726 | } |
1714 | spin_unlock(&mm->page_table_lock); | 1727 | spin_unlock(&mm->page_table_lock); |
1715 | flush_tlb_range(vma, start, end); | 1728 | flush_tlb_range(vma, start, end); |
1729 | mmu_notifier_invalidate_range_end(mm, start, end); | ||
1716 | list_for_each_entry_safe(page, tmp, &page_list, lru) { | 1730 | list_for_each_entry_safe(page, tmp, &page_list, lru) { |
1717 | list_del(&page->lru); | 1731 | list_del(&page->lru); |
1718 | put_page(page); | 1732 | put_page(page); |
@@ -1928,6 +1942,18 @@ retry: | |||
1928 | lock_page(page); | 1942 | lock_page(page); |
1929 | } | 1943 | } |
1930 | 1944 | ||
1945 | /* | ||
1946 | * If we are going to COW a private mapping later, we examine the | ||
1947 | * pending reservations for this page now. This will ensure that | ||
1948 | * any allocations necessary to record that reservation occur outside | ||
1949 | * the spinlock. | ||
1950 | */ | ||
1951 | if (write_access && !(vma->vm_flags & VM_SHARED)) | ||
1952 | if (vma_needs_reservation(h, vma, address) < 0) { | ||
1953 | ret = VM_FAULT_OOM; | ||
1954 | goto backout_unlocked; | ||
1955 | } | ||
1956 | |||
1931 | spin_lock(&mm->page_table_lock); | 1957 | spin_lock(&mm->page_table_lock); |
1932 | size = i_size_read(mapping->host) >> huge_page_shift(h); | 1958 | size = i_size_read(mapping->host) >> huge_page_shift(h); |
1933 | if (idx >= size) | 1959 | if (idx >= size) |
@@ -1953,6 +1979,7 @@ out: | |||
1953 | 1979 | ||
1954 | backout: | 1980 | backout: |
1955 | spin_unlock(&mm->page_table_lock); | 1981 | spin_unlock(&mm->page_table_lock); |
1982 | backout_unlocked: | ||
1956 | unlock_page(page); | 1983 | unlock_page(page); |
1957 | put_page(page); | 1984 | put_page(page); |
1958 | goto out; | 1985 | goto out; |
@@ -1964,6 +1991,7 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, | |||
1964 | pte_t *ptep; | 1991 | pte_t *ptep; |
1965 | pte_t entry; | 1992 | pte_t entry; |
1966 | int ret; | 1993 | int ret; |
1994 | struct page *pagecache_page = NULL; | ||
1967 | static DEFINE_MUTEX(hugetlb_instantiation_mutex); | 1995 | static DEFINE_MUTEX(hugetlb_instantiation_mutex); |
1968 | struct hstate *h = hstate_vma(vma); | 1996 | struct hstate *h = hstate_vma(vma); |
1969 | 1997 | ||
@@ -1980,25 +2008,44 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, | |||
1980 | entry = huge_ptep_get(ptep); | 2008 | entry = huge_ptep_get(ptep); |
1981 | if (huge_pte_none(entry)) { | 2009 | if (huge_pte_none(entry)) { |
1982 | ret = hugetlb_no_page(mm, vma, address, ptep, write_access); | 2010 | ret = hugetlb_no_page(mm, vma, address, ptep, write_access); |
1983 | mutex_unlock(&hugetlb_instantiation_mutex); | 2011 | goto out_unlock; |
1984 | return ret; | ||
1985 | } | 2012 | } |
1986 | 2013 | ||
1987 | ret = 0; | 2014 | ret = 0; |
1988 | 2015 | ||
2016 | /* | ||
2017 | * If we are going to COW the mapping later, we examine the pending | ||
2018 | * reservations for this page now. This will ensure that any | ||
2019 | * allocations necessary to record that reservation occur outside the | ||
2020 | * spinlock. For private mappings, we also lookup the pagecache | ||
2021 | * page now as it is used to determine if a reservation has been | ||
2022 | * consumed. | ||
2023 | */ | ||
2024 | if (write_access && !pte_write(entry)) { | ||
2025 | if (vma_needs_reservation(h, vma, address) < 0) { | ||
2026 | ret = VM_FAULT_OOM; | ||
2027 | goto out_unlock; | ||
2028 | } | ||
2029 | |||
2030 | if (!(vma->vm_flags & VM_SHARED)) | ||
2031 | pagecache_page = hugetlbfs_pagecache_page(h, | ||
2032 | vma, address); | ||
2033 | } | ||
2034 | |||
1989 | spin_lock(&mm->page_table_lock); | 2035 | spin_lock(&mm->page_table_lock); |
1990 | /* Check for a racing update before calling hugetlb_cow */ | 2036 | /* Check for a racing update before calling hugetlb_cow */ |
1991 | if (likely(pte_same(entry, huge_ptep_get(ptep)))) | 2037 | if (likely(pte_same(entry, huge_ptep_get(ptep)))) |
1992 | if (write_access && !pte_write(entry)) { | 2038 | if (write_access && !pte_write(entry)) |
1993 | struct page *page; | 2039 | ret = hugetlb_cow(mm, vma, address, ptep, entry, |
1994 | page = hugetlbfs_pagecache_page(h, vma, address); | 2040 | pagecache_page); |
1995 | ret = hugetlb_cow(mm, vma, address, ptep, entry, page); | ||
1996 | if (page) { | ||
1997 | unlock_page(page); | ||
1998 | put_page(page); | ||
1999 | } | ||
2000 | } | ||
2001 | spin_unlock(&mm->page_table_lock); | 2041 | spin_unlock(&mm->page_table_lock); |
2042 | |||
2043 | if (pagecache_page) { | ||
2044 | unlock_page(pagecache_page); | ||
2045 | put_page(pagecache_page); | ||
2046 | } | ||
2047 | |||
2048 | out_unlock: | ||
2002 | mutex_unlock(&hugetlb_instantiation_mutex); | 2049 | mutex_unlock(&hugetlb_instantiation_mutex); |
2003 | 2050 | ||
2004 | return ret; | 2051 | return ret; |
diff --git a/mm/madvise.c b/mm/madvise.c index 23a0ec3e0ea0..f9349c18a1b5 100644 --- a/mm/madvise.c +++ b/mm/madvise.c | |||
@@ -132,10 +132,10 @@ static long madvise_willneed(struct vm_area_struct * vma, | |||
132 | * Application no longer needs these pages. If the pages are dirty, | 132 | * Application no longer needs these pages. If the pages are dirty, |
133 | * it's OK to just throw them away. The app will be more careful about | 133 | * it's OK to just throw them away. The app will be more careful about |
134 | * data it wants to keep. Be sure to free swap resources too. The | 134 | * data it wants to keep. Be sure to free swap resources too. The |
135 | * zap_page_range call sets things up for refill_inactive to actually free | 135 | * zap_page_range call sets things up for shrink_active_list to actually free |
136 | * these pages later if no one else has touched them in the meantime, | 136 | * these pages later if no one else has touched them in the meantime, |
137 | * although we could add these pages to a global reuse list for | 137 | * although we could add these pages to a global reuse list for |
138 | * refill_inactive to pick up before reclaiming other pages. | 138 | * shrink_active_list to pick up before reclaiming other pages. |
139 | * | 139 | * |
140 | * NB: This interface discards data rather than pushes it out to swap, | 140 | * NB: This interface discards data rather than pushes it out to swap, |
141 | * as some implementations do. This has performance implications for | 141 | * as some implementations do. This has performance implications for |
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index fba566c51322..0f1f7a7374ba 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -796,6 +796,8 @@ int mem_cgroup_shrink_usage(struct mm_struct *mm, gfp_t gfp_mask) | |||
796 | 796 | ||
797 | if (mem_cgroup_subsys.disabled) | 797 | if (mem_cgroup_subsys.disabled) |
798 | return 0; | 798 | return 0; |
799 | if (!mm) | ||
800 | return 0; | ||
799 | 801 | ||
800 | rcu_read_lock(); | 802 | rcu_read_lock(); |
801 | mem = mem_cgroup_from_task(rcu_dereference(mm->owner)); | 803 | mem = mem_cgroup_from_task(rcu_dereference(mm->owner)); |
@@ -1168,9 +1170,6 @@ static void mem_cgroup_move_task(struct cgroup_subsys *ss, | |||
1168 | mem = mem_cgroup_from_cont(cont); | 1170 | mem = mem_cgroup_from_cont(cont); |
1169 | old_mem = mem_cgroup_from_cont(old_cont); | 1171 | old_mem = mem_cgroup_from_cont(old_cont); |
1170 | 1172 | ||
1171 | if (mem == old_mem) | ||
1172 | goto out; | ||
1173 | |||
1174 | /* | 1173 | /* |
1175 | * Only thread group leaders are allowed to migrate, the mm_struct is | 1174 | * Only thread group leaders are allowed to migrate, the mm_struct is |
1176 | * in effect owned by the leader | 1175 | * in effect owned by the leader |
diff --git a/mm/memory.c b/mm/memory.c index a8ca04faaea6..1002f473f497 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include <linux/init.h> | 51 | #include <linux/init.h> |
52 | #include <linux/writeback.h> | 52 | #include <linux/writeback.h> |
53 | #include <linux/memcontrol.h> | 53 | #include <linux/memcontrol.h> |
54 | #include <linux/mmu_notifier.h> | ||
54 | 55 | ||
55 | #include <asm/pgalloc.h> | 56 | #include <asm/pgalloc.h> |
56 | #include <asm/uaccess.h> | 57 | #include <asm/uaccess.h> |
@@ -652,6 +653,7 @@ int copy_page_range(struct mm_struct *dst_mm, struct mm_struct *src_mm, | |||
652 | unsigned long next; | 653 | unsigned long next; |
653 | unsigned long addr = vma->vm_start; | 654 | unsigned long addr = vma->vm_start; |
654 | unsigned long end = vma->vm_end; | 655 | unsigned long end = vma->vm_end; |
656 | int ret; | ||
655 | 657 | ||
656 | /* | 658 | /* |
657 | * Don't copy ptes where a page fault will fill them correctly. | 659 | * Don't copy ptes where a page fault will fill them correctly. |
@@ -667,17 +669,33 @@ int copy_page_range(struct mm_struct *dst_mm, struct mm_struct *src_mm, | |||
667 | if (is_vm_hugetlb_page(vma)) | 669 | if (is_vm_hugetlb_page(vma)) |
668 | return copy_hugetlb_page_range(dst_mm, src_mm, vma); | 670 | return copy_hugetlb_page_range(dst_mm, src_mm, vma); |
669 | 671 | ||
672 | /* | ||
673 | * We need to invalidate the secondary MMU mappings only when | ||
674 | * there could be a permission downgrade on the ptes of the | ||
675 | * parent mm. And a permission downgrade will only happen if | ||
676 | * is_cow_mapping() returns true. | ||
677 | */ | ||
678 | if (is_cow_mapping(vma->vm_flags)) | ||
679 | mmu_notifier_invalidate_range_start(src_mm, addr, end); | ||
680 | |||
681 | ret = 0; | ||
670 | dst_pgd = pgd_offset(dst_mm, addr); | 682 | dst_pgd = pgd_offset(dst_mm, addr); |
671 | src_pgd = pgd_offset(src_mm, addr); | 683 | src_pgd = pgd_offset(src_mm, addr); |
672 | do { | 684 | do { |
673 | next = pgd_addr_end(addr, end); | 685 | next = pgd_addr_end(addr, end); |
674 | if (pgd_none_or_clear_bad(src_pgd)) | 686 | if (pgd_none_or_clear_bad(src_pgd)) |
675 | continue; | 687 | continue; |
676 | if (copy_pud_range(dst_mm, src_mm, dst_pgd, src_pgd, | 688 | if (unlikely(copy_pud_range(dst_mm, src_mm, dst_pgd, src_pgd, |
677 | vma, addr, next)) | 689 | vma, addr, next))) { |
678 | return -ENOMEM; | 690 | ret = -ENOMEM; |
691 | break; | ||
692 | } | ||
679 | } while (dst_pgd++, src_pgd++, addr = next, addr != end); | 693 | } while (dst_pgd++, src_pgd++, addr = next, addr != end); |
680 | return 0; | 694 | |
695 | if (is_cow_mapping(vma->vm_flags)) | ||
696 | mmu_notifier_invalidate_range_end(src_mm, | ||
697 | vma->vm_start, end); | ||
698 | return ret; | ||
681 | } | 699 | } |
682 | 700 | ||
683 | static unsigned long zap_pte_range(struct mmu_gather *tlb, | 701 | static unsigned long zap_pte_range(struct mmu_gather *tlb, |
@@ -881,7 +899,9 @@ unsigned long unmap_vmas(struct mmu_gather **tlbp, | |||
881 | unsigned long start = start_addr; | 899 | unsigned long start = start_addr; |
882 | spinlock_t *i_mmap_lock = details? details->i_mmap_lock: NULL; | 900 | spinlock_t *i_mmap_lock = details? details->i_mmap_lock: NULL; |
883 | int fullmm = (*tlbp)->fullmm; | 901 | int fullmm = (*tlbp)->fullmm; |
902 | struct mm_struct *mm = vma->vm_mm; | ||
884 | 903 | ||
904 | mmu_notifier_invalidate_range_start(mm, start_addr, end_addr); | ||
885 | for ( ; vma && vma->vm_start < end_addr; vma = vma->vm_next) { | 905 | for ( ; vma && vma->vm_start < end_addr; vma = vma->vm_next) { |
886 | unsigned long end; | 906 | unsigned long end; |
887 | 907 | ||
@@ -946,6 +966,7 @@ unsigned long unmap_vmas(struct mmu_gather **tlbp, | |||
946 | } | 966 | } |
947 | } | 967 | } |
948 | out: | 968 | out: |
969 | mmu_notifier_invalidate_range_end(mm, start_addr, end_addr); | ||
949 | return start; /* which is now the end (or restart) address */ | 970 | return start; /* which is now the end (or restart) address */ |
950 | } | 971 | } |
951 | 972 | ||
@@ -973,6 +994,29 @@ unsigned long zap_page_range(struct vm_area_struct *vma, unsigned long address, | |||
973 | return end; | 994 | return end; |
974 | } | 995 | } |
975 | 996 | ||
997 | /** | ||
998 | * zap_vma_ptes - remove ptes mapping the vma | ||
999 | * @vma: vm_area_struct holding ptes to be zapped | ||
1000 | * @address: starting address of pages to zap | ||
1001 | * @size: number of bytes to zap | ||
1002 | * | ||
1003 | * This function only unmaps ptes assigned to VM_PFNMAP vmas. | ||
1004 | * | ||
1005 | * The entire address range must be fully contained within the vma. | ||
1006 | * | ||
1007 | * Returns 0 if successful. | ||
1008 | */ | ||
1009 | int zap_vma_ptes(struct vm_area_struct *vma, unsigned long address, | ||
1010 | unsigned long size) | ||
1011 | { | ||
1012 | if (address < vma->vm_start || address + size > vma->vm_end || | ||
1013 | !(vma->vm_flags & VM_PFNMAP)) | ||
1014 | return -1; | ||
1015 | zap_page_range(vma, address, size, NULL); | ||
1016 | return 0; | ||
1017 | } | ||
1018 | EXPORT_SYMBOL_GPL(zap_vma_ptes); | ||
1019 | |||
976 | /* | 1020 | /* |
977 | * Do a quick page-table lookup for a single page. | 1021 | * Do a quick page-table lookup for a single page. |
978 | */ | 1022 | */ |
@@ -1616,10 +1660,11 @@ int apply_to_page_range(struct mm_struct *mm, unsigned long addr, | |||
1616 | { | 1660 | { |
1617 | pgd_t *pgd; | 1661 | pgd_t *pgd; |
1618 | unsigned long next; | 1662 | unsigned long next; |
1619 | unsigned long end = addr + size; | 1663 | unsigned long start = addr, end = addr + size; |
1620 | int err; | 1664 | int err; |
1621 | 1665 | ||
1622 | BUG_ON(addr >= end); | 1666 | BUG_ON(addr >= end); |
1667 | mmu_notifier_invalidate_range_start(mm, start, end); | ||
1623 | pgd = pgd_offset(mm, addr); | 1668 | pgd = pgd_offset(mm, addr); |
1624 | do { | 1669 | do { |
1625 | next = pgd_addr_end(addr, end); | 1670 | next = pgd_addr_end(addr, end); |
@@ -1627,6 +1672,7 @@ int apply_to_page_range(struct mm_struct *mm, unsigned long addr, | |||
1627 | if (err) | 1672 | if (err) |
1628 | break; | 1673 | break; |
1629 | } while (pgd++, addr = next, addr != end); | 1674 | } while (pgd++, addr = next, addr != end); |
1675 | mmu_notifier_invalidate_range_end(mm, start, end); | ||
1630 | return err; | 1676 | return err; |
1631 | } | 1677 | } |
1632 | EXPORT_SYMBOL_GPL(apply_to_page_range); | 1678 | EXPORT_SYMBOL_GPL(apply_to_page_range); |
@@ -1743,7 +1789,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
1743 | * not dirty accountable. | 1789 | * not dirty accountable. |
1744 | */ | 1790 | */ |
1745 | if (PageAnon(old_page)) { | 1791 | if (PageAnon(old_page)) { |
1746 | if (!TestSetPageLocked(old_page)) { | 1792 | if (trylock_page(old_page)) { |
1747 | reuse = can_share_swap_page(old_page); | 1793 | reuse = can_share_swap_page(old_page); |
1748 | unlock_page(old_page); | 1794 | unlock_page(old_page); |
1749 | } | 1795 | } |
@@ -1839,7 +1885,7 @@ gotten: | |||
1839 | * seen in the presence of one thread doing SMC and another | 1885 | * seen in the presence of one thread doing SMC and another |
1840 | * thread doing COW. | 1886 | * thread doing COW. |
1841 | */ | 1887 | */ |
1842 | ptep_clear_flush(vma, address, page_table); | 1888 | ptep_clear_flush_notify(vma, address, page_table); |
1843 | set_pte_at(mm, address, page_table, entry); | 1889 | set_pte_at(mm, address, page_table, entry); |
1844 | update_mmu_cache(vma, address, entry); | 1890 | update_mmu_cache(vma, address, entry); |
1845 | lru_cache_add_active(new_page); | 1891 | lru_cache_add_active(new_page); |
@@ -2719,16 +2765,26 @@ int make_pages_present(unsigned long addr, unsigned long end) | |||
2719 | 2765 | ||
2720 | vma = find_vma(current->mm, addr); | 2766 | vma = find_vma(current->mm, addr); |
2721 | if (!vma) | 2767 | if (!vma) |
2722 | return -1; | 2768 | return -ENOMEM; |
2723 | write = (vma->vm_flags & VM_WRITE) != 0; | 2769 | write = (vma->vm_flags & VM_WRITE) != 0; |
2724 | BUG_ON(addr >= end); | 2770 | BUG_ON(addr >= end); |
2725 | BUG_ON(end > vma->vm_end); | 2771 | BUG_ON(end > vma->vm_end); |
2726 | len = DIV_ROUND_UP(end, PAGE_SIZE) - addr/PAGE_SIZE; | 2772 | len = DIV_ROUND_UP(end, PAGE_SIZE) - addr/PAGE_SIZE; |
2727 | ret = get_user_pages(current, current->mm, addr, | 2773 | ret = get_user_pages(current, current->mm, addr, |
2728 | len, write, 0, NULL, NULL); | 2774 | len, write, 0, NULL, NULL); |
2729 | if (ret < 0) | 2775 | if (ret < 0) { |
2776 | /* | ||
2777 | SUS require strange return value to mlock | ||
2778 | - invalid addr generate to ENOMEM. | ||
2779 | - out of memory should generate EAGAIN. | ||
2780 | */ | ||
2781 | if (ret == -EFAULT) | ||
2782 | ret = -ENOMEM; | ||
2783 | else if (ret == -ENOMEM) | ||
2784 | ret = -EAGAIN; | ||
2730 | return ret; | 2785 | return ret; |
2731 | return ret == len ? 0 : -1; | 2786 | } |
2787 | return ret == len ? 0 : -ENOMEM; | ||
2732 | } | 2788 | } |
2733 | 2789 | ||
2734 | #if !defined(__HAVE_ARCH_GATE_AREA) | 2790 | #if !defined(__HAVE_ARCH_GATE_AREA) |
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index e550bec20582..83369058ec13 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c | |||
@@ -803,7 +803,6 @@ static int migrate_to_node(struct mm_struct *mm, int source, int dest, | |||
803 | int do_migrate_pages(struct mm_struct *mm, | 803 | int do_migrate_pages(struct mm_struct *mm, |
804 | const nodemask_t *from_nodes, const nodemask_t *to_nodes, int flags) | 804 | const nodemask_t *from_nodes, const nodemask_t *to_nodes, int flags) |
805 | { | 805 | { |
806 | LIST_HEAD(pagelist); | ||
807 | int busy = 0; | 806 | int busy = 0; |
808 | int err = 0; | 807 | int err = 0; |
809 | nodemask_t tmp; | 808 | nodemask_t tmp; |
diff --git a/mm/migrate.c b/mm/migrate.c index 153572fb60b8..2a80136b23bb 100644 --- a/mm/migrate.c +++ b/mm/migrate.c | |||
@@ -605,7 +605,7 @@ static int move_to_new_page(struct page *newpage, struct page *page) | |||
605 | * establishing additional references. We are the only one | 605 | * establishing additional references. We are the only one |
606 | * holding a reference to the new page at this point. | 606 | * holding a reference to the new page at this point. |
607 | */ | 607 | */ |
608 | if (TestSetPageLocked(newpage)) | 608 | if (!trylock_page(newpage)) |
609 | BUG(); | 609 | BUG(); |
610 | 610 | ||
611 | /* Prepare mapping for the new page.*/ | 611 | /* Prepare mapping for the new page.*/ |
@@ -667,7 +667,7 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private, | |||
667 | BUG_ON(charge); | 667 | BUG_ON(charge); |
668 | 668 | ||
669 | rc = -EAGAIN; | 669 | rc = -EAGAIN; |
670 | if (TestSetPageLocked(page)) { | 670 | if (!trylock_page(page)) { |
671 | if (!force) | 671 | if (!force) |
672 | goto move_newpage; | 672 | goto move_newpage; |
673 | lock_page(page); | 673 | lock_page(page); |
diff --git a/mm/mlock.c b/mm/mlock.c index 7b2656055d6a..01fbe93eff5c 100644 --- a/mm/mlock.c +++ b/mm/mlock.c | |||
@@ -78,8 +78,6 @@ success: | |||
78 | 78 | ||
79 | mm->locked_vm -= pages; | 79 | mm->locked_vm -= pages; |
80 | out: | 80 | out: |
81 | if (ret == -ENOMEM) | ||
82 | ret = -EAGAIN; | ||
83 | return ret; | 81 | return ret; |
84 | } | 82 | } |
85 | 83 | ||
diff --git a/mm/mm_init.c b/mm/mm_init.c index c6af41ea9994..936ef2efd892 100644 --- a/mm/mm_init.c +++ b/mm/mm_init.c | |||
@@ -14,6 +14,10 @@ | |||
14 | #ifdef CONFIG_DEBUG_MEMORY_INIT | 14 | #ifdef CONFIG_DEBUG_MEMORY_INIT |
15 | int __meminitdata mminit_loglevel; | 15 | int __meminitdata mminit_loglevel; |
16 | 16 | ||
17 | #ifndef SECTIONS_SHIFT | ||
18 | #define SECTIONS_SHIFT 0 | ||
19 | #endif | ||
20 | |||
17 | /* The zonelists are simply reported, validation is manual. */ | 21 | /* The zonelists are simply reported, validation is manual. */ |
18 | void mminit_verify_zonelist(void) | 22 | void mminit_verify_zonelist(void) |
19 | { | 23 | { |
@@ -74,11 +78,7 @@ void __init mminit_verify_pageflags_layout(void) | |||
74 | NR_PAGEFLAGS); | 78 | NR_PAGEFLAGS); |
75 | mminit_dprintk(MMINIT_TRACE, "pageflags_layout_shifts", | 79 | mminit_dprintk(MMINIT_TRACE, "pageflags_layout_shifts", |
76 | "Section %d Node %d Zone %d\n", | 80 | "Section %d Node %d Zone %d\n", |
77 | #ifdef SECTIONS_SHIFT | ||
78 | SECTIONS_SHIFT, | 81 | SECTIONS_SHIFT, |
79 | #else | ||
80 | 0, | ||
81 | #endif | ||
82 | NODES_SHIFT, | 82 | NODES_SHIFT, |
83 | ZONES_SHIFT); | 83 | ZONES_SHIFT); |
84 | mminit_dprintk(MMINIT_TRACE, "pageflags_layout_offsets", | 84 | mminit_dprintk(MMINIT_TRACE, "pageflags_layout_offsets", |
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/mount.h> | 26 | #include <linux/mount.h> |
27 | #include <linux/mempolicy.h> | 27 | #include <linux/mempolicy.h> |
28 | #include <linux/rmap.h> | 28 | #include <linux/rmap.h> |
29 | #include <linux/mmu_notifier.h> | ||
29 | 30 | ||
30 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
31 | #include <asm/cacheflush.h> | 32 | #include <asm/cacheflush.h> |
@@ -369,7 +370,7 @@ find_vma_prepare(struct mm_struct *mm, unsigned long addr, | |||
369 | if (vma_tmp->vm_end > addr) { | 370 | if (vma_tmp->vm_end > addr) { |
370 | vma = vma_tmp; | 371 | vma = vma_tmp; |
371 | if (vma_tmp->vm_start <= addr) | 372 | if (vma_tmp->vm_start <= addr) |
372 | return vma; | 373 | break; |
373 | __rb_link = &__rb_parent->rb_left; | 374 | __rb_link = &__rb_parent->rb_left; |
374 | } else { | 375 | } else { |
375 | rb_prev = __rb_parent; | 376 | rb_prev = __rb_parent; |
@@ -2061,6 +2062,7 @@ void exit_mmap(struct mm_struct *mm) | |||
2061 | 2062 | ||
2062 | /* mm's last user has gone, and its about to be pulled down */ | 2063 | /* mm's last user has gone, and its about to be pulled down */ |
2063 | arch_exit_mmap(mm); | 2064 | arch_exit_mmap(mm); |
2065 | mmu_notifier_release(mm); | ||
2064 | 2066 | ||
2065 | lru_add_drain(); | 2067 | lru_add_drain(); |
2066 | flush_cache_mm(mm); | 2068 | flush_cache_mm(mm); |
@@ -2268,3 +2270,167 @@ int install_special_mapping(struct mm_struct *mm, | |||
2268 | 2270 | ||
2269 | return 0; | 2271 | return 0; |
2270 | } | 2272 | } |
2273 | |||
2274 | static DEFINE_MUTEX(mm_all_locks_mutex); | ||
2275 | |||
2276 | static void vm_lock_anon_vma(struct mm_struct *mm, struct anon_vma *anon_vma) | ||
2277 | { | ||
2278 | if (!test_bit(0, (unsigned long *) &anon_vma->head.next)) { | ||
2279 | /* | ||
2280 | * The LSB of head.next can't change from under us | ||
2281 | * because we hold the mm_all_locks_mutex. | ||
2282 | */ | ||
2283 | spin_lock_nest_lock(&anon_vma->lock, &mm->mmap_sem); | ||
2284 | /* | ||
2285 | * We can safely modify head.next after taking the | ||
2286 | * anon_vma->lock. If some other vma in this mm shares | ||
2287 | * the same anon_vma we won't take it again. | ||
2288 | * | ||
2289 | * No need of atomic instructions here, head.next | ||
2290 | * can't change from under us thanks to the | ||
2291 | * anon_vma->lock. | ||
2292 | */ | ||
2293 | if (__test_and_set_bit(0, (unsigned long *) | ||
2294 | &anon_vma->head.next)) | ||
2295 | BUG(); | ||
2296 | } | ||
2297 | } | ||
2298 | |||
2299 | static void vm_lock_mapping(struct mm_struct *mm, struct address_space *mapping) | ||
2300 | { | ||
2301 | if (!test_bit(AS_MM_ALL_LOCKS, &mapping->flags)) { | ||
2302 | /* | ||
2303 | * AS_MM_ALL_LOCKS can't change from under us because | ||
2304 | * we hold the mm_all_locks_mutex. | ||
2305 | * | ||
2306 | * Operations on ->flags have to be atomic because | ||
2307 | * even if AS_MM_ALL_LOCKS is stable thanks to the | ||
2308 | * mm_all_locks_mutex, there may be other cpus | ||
2309 | * changing other bitflags in parallel to us. | ||
2310 | */ | ||
2311 | if (test_and_set_bit(AS_MM_ALL_LOCKS, &mapping->flags)) | ||
2312 | BUG(); | ||
2313 | spin_lock_nest_lock(&mapping->i_mmap_lock, &mm->mmap_sem); | ||
2314 | } | ||
2315 | } | ||
2316 | |||
2317 | /* | ||
2318 | * This operation locks against the VM for all pte/vma/mm related | ||
2319 | * operations that could ever happen on a certain mm. This includes | ||
2320 | * vmtruncate, try_to_unmap, and all page faults. | ||
2321 | * | ||
2322 | * The caller must take the mmap_sem in write mode before calling | ||
2323 | * mm_take_all_locks(). The caller isn't allowed to release the | ||
2324 | * mmap_sem until mm_drop_all_locks() returns. | ||
2325 | * | ||
2326 | * mmap_sem in write mode is required in order to block all operations | ||
2327 | * that could modify pagetables and free pages without need of | ||
2328 | * altering the vma layout (for example populate_range() with | ||
2329 | * nonlinear vmas). It's also needed in write mode to avoid new | ||
2330 | * anon_vmas to be associated with existing vmas. | ||
2331 | * | ||
2332 | * A single task can't take more than one mm_take_all_locks() in a row | ||
2333 | * or it would deadlock. | ||
2334 | * | ||
2335 | * The LSB in anon_vma->head.next and the AS_MM_ALL_LOCKS bitflag in | ||
2336 | * mapping->flags avoid to take the same lock twice, if more than one | ||
2337 | * vma in this mm is backed by the same anon_vma or address_space. | ||
2338 | * | ||
2339 | * We can take all the locks in random order because the VM code | ||
2340 | * taking i_mmap_lock or anon_vma->lock outside the mmap_sem never | ||
2341 | * takes more than one of them in a row. Secondly we're protected | ||
2342 | * against a concurrent mm_take_all_locks() by the mm_all_locks_mutex. | ||
2343 | * | ||
2344 | * mm_take_all_locks() and mm_drop_all_locks are expensive operations | ||
2345 | * that may have to take thousand of locks. | ||
2346 | * | ||
2347 | * mm_take_all_locks() can fail if it's interrupted by signals. | ||
2348 | */ | ||
2349 | int mm_take_all_locks(struct mm_struct *mm) | ||
2350 | { | ||
2351 | struct vm_area_struct *vma; | ||
2352 | int ret = -EINTR; | ||
2353 | |||
2354 | BUG_ON(down_read_trylock(&mm->mmap_sem)); | ||
2355 | |||
2356 | mutex_lock(&mm_all_locks_mutex); | ||
2357 | |||
2358 | for (vma = mm->mmap; vma; vma = vma->vm_next) { | ||
2359 | if (signal_pending(current)) | ||
2360 | goto out_unlock; | ||
2361 | if (vma->vm_file && vma->vm_file->f_mapping) | ||
2362 | vm_lock_mapping(mm, vma->vm_file->f_mapping); | ||
2363 | } | ||
2364 | |||
2365 | for (vma = mm->mmap; vma; vma = vma->vm_next) { | ||
2366 | if (signal_pending(current)) | ||
2367 | goto out_unlock; | ||
2368 | if (vma->anon_vma) | ||
2369 | vm_lock_anon_vma(mm, vma->anon_vma); | ||
2370 | } | ||
2371 | |||
2372 | ret = 0; | ||
2373 | |||
2374 | out_unlock: | ||
2375 | if (ret) | ||
2376 | mm_drop_all_locks(mm); | ||
2377 | |||
2378 | return ret; | ||
2379 | } | ||
2380 | |||
2381 | static void vm_unlock_anon_vma(struct anon_vma *anon_vma) | ||
2382 | { | ||
2383 | if (test_bit(0, (unsigned long *) &anon_vma->head.next)) { | ||
2384 | /* | ||
2385 | * The LSB of head.next can't change to 0 from under | ||
2386 | * us because we hold the mm_all_locks_mutex. | ||
2387 | * | ||
2388 | * We must however clear the bitflag before unlocking | ||
2389 | * the vma so the users using the anon_vma->head will | ||
2390 | * never see our bitflag. | ||
2391 | * | ||
2392 | * No need of atomic instructions here, head.next | ||
2393 | * can't change from under us until we release the | ||
2394 | * anon_vma->lock. | ||
2395 | */ | ||
2396 | if (!__test_and_clear_bit(0, (unsigned long *) | ||
2397 | &anon_vma->head.next)) | ||
2398 | BUG(); | ||
2399 | spin_unlock(&anon_vma->lock); | ||
2400 | } | ||
2401 | } | ||
2402 | |||
2403 | static void vm_unlock_mapping(struct address_space *mapping) | ||
2404 | { | ||
2405 | if (test_bit(AS_MM_ALL_LOCKS, &mapping->flags)) { | ||
2406 | /* | ||
2407 | * AS_MM_ALL_LOCKS can't change to 0 from under us | ||
2408 | * because we hold the mm_all_locks_mutex. | ||
2409 | */ | ||
2410 | spin_unlock(&mapping->i_mmap_lock); | ||
2411 | if (!test_and_clear_bit(AS_MM_ALL_LOCKS, | ||
2412 | &mapping->flags)) | ||
2413 | BUG(); | ||
2414 | } | ||
2415 | } | ||
2416 | |||
2417 | /* | ||
2418 | * The mmap_sem cannot be released by the caller until | ||
2419 | * mm_drop_all_locks() returns. | ||
2420 | */ | ||
2421 | void mm_drop_all_locks(struct mm_struct *mm) | ||
2422 | { | ||
2423 | struct vm_area_struct *vma; | ||
2424 | |||
2425 | BUG_ON(down_read_trylock(&mm->mmap_sem)); | ||
2426 | BUG_ON(!mutex_is_locked(&mm_all_locks_mutex)); | ||
2427 | |||
2428 | for (vma = mm->mmap; vma; vma = vma->vm_next) { | ||
2429 | if (vma->anon_vma) | ||
2430 | vm_unlock_anon_vma(vma->anon_vma); | ||
2431 | if (vma->vm_file && vma->vm_file->f_mapping) | ||
2432 | vm_unlock_mapping(vma->vm_file->f_mapping); | ||
2433 | } | ||
2434 | |||
2435 | mutex_unlock(&mm_all_locks_mutex); | ||
2436 | } | ||
diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c new file mode 100644 index 000000000000..5f4ef0250bee --- /dev/null +++ b/mm/mmu_notifier.c | |||
@@ -0,0 +1,277 @@ | |||
1 | /* | ||
2 | * linux/mm/mmu_notifier.c | ||
3 | * | ||
4 | * Copyright (C) 2008 Qumranet, Inc. | ||
5 | * Copyright (C) 2008 SGI | ||
6 | * Christoph Lameter <clameter@sgi.com> | ||
7 | * | ||
8 | * This work is licensed under the terms of the GNU GPL, version 2. See | ||
9 | * the COPYING file in the top-level directory. | ||
10 | */ | ||
11 | |||
12 | #include <linux/rculist.h> | ||
13 | #include <linux/mmu_notifier.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/mm.h> | ||
16 | #include <linux/err.h> | ||
17 | #include <linux/rcupdate.h> | ||
18 | #include <linux/sched.h> | ||
19 | |||
20 | /* | ||
21 | * This function can't run concurrently against mmu_notifier_register | ||
22 | * because mm->mm_users > 0 during mmu_notifier_register and exit_mmap | ||
23 | * runs with mm_users == 0. Other tasks may still invoke mmu notifiers | ||
24 | * in parallel despite there being no task using this mm any more, | ||
25 | * through the vmas outside of the exit_mmap context, such as with | ||
26 | * vmtruncate. This serializes against mmu_notifier_unregister with | ||
27 | * the mmu_notifier_mm->lock in addition to RCU and it serializes | ||
28 | * against the other mmu notifiers with RCU. struct mmu_notifier_mm | ||
29 | * can't go away from under us as exit_mmap holds an mm_count pin | ||
30 | * itself. | ||
31 | */ | ||
32 | void __mmu_notifier_release(struct mm_struct *mm) | ||
33 | { | ||
34 | struct mmu_notifier *mn; | ||
35 | |||
36 | spin_lock(&mm->mmu_notifier_mm->lock); | ||
37 | while (unlikely(!hlist_empty(&mm->mmu_notifier_mm->list))) { | ||
38 | mn = hlist_entry(mm->mmu_notifier_mm->list.first, | ||
39 | struct mmu_notifier, | ||
40 | hlist); | ||
41 | /* | ||
42 | * We arrived before mmu_notifier_unregister so | ||
43 | * mmu_notifier_unregister will do nothing other than | ||
44 | * to wait ->release to finish and | ||
45 | * mmu_notifier_unregister to return. | ||
46 | */ | ||
47 | hlist_del_init_rcu(&mn->hlist); | ||
48 | /* | ||
49 | * RCU here will block mmu_notifier_unregister until | ||
50 | * ->release returns. | ||
51 | */ | ||
52 | rcu_read_lock(); | ||
53 | spin_unlock(&mm->mmu_notifier_mm->lock); | ||
54 | /* | ||
55 | * if ->release runs before mmu_notifier_unregister it | ||
56 | * must be handled as it's the only way for the driver | ||
57 | * to flush all existing sptes and stop the driver | ||
58 | * from establishing any more sptes before all the | ||
59 | * pages in the mm are freed. | ||
60 | */ | ||
61 | if (mn->ops->release) | ||
62 | mn->ops->release(mn, mm); | ||
63 | rcu_read_unlock(); | ||
64 | spin_lock(&mm->mmu_notifier_mm->lock); | ||
65 | } | ||
66 | spin_unlock(&mm->mmu_notifier_mm->lock); | ||
67 | |||
68 | /* | ||
69 | * synchronize_rcu here prevents mmu_notifier_release to | ||
70 | * return to exit_mmap (which would proceed freeing all pages | ||
71 | * in the mm) until the ->release method returns, if it was | ||
72 | * invoked by mmu_notifier_unregister. | ||
73 | * | ||
74 | * The mmu_notifier_mm can't go away from under us because one | ||
75 | * mm_count is hold by exit_mmap. | ||
76 | */ | ||
77 | synchronize_rcu(); | ||
78 | } | ||
79 | |||
80 | /* | ||
81 | * If no young bitflag is supported by the hardware, ->clear_flush_young can | ||
82 | * unmap the address and return 1 or 0 depending if the mapping previously | ||
83 | * existed or not. | ||
84 | */ | ||
85 | int __mmu_notifier_clear_flush_young(struct mm_struct *mm, | ||
86 | unsigned long address) | ||
87 | { | ||
88 | struct mmu_notifier *mn; | ||
89 | struct hlist_node *n; | ||
90 | int young = 0; | ||
91 | |||
92 | rcu_read_lock(); | ||
93 | hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list, hlist) { | ||
94 | if (mn->ops->clear_flush_young) | ||
95 | young |= mn->ops->clear_flush_young(mn, mm, address); | ||
96 | } | ||
97 | rcu_read_unlock(); | ||
98 | |||
99 | return young; | ||
100 | } | ||
101 | |||
102 | void __mmu_notifier_invalidate_page(struct mm_struct *mm, | ||
103 | unsigned long address) | ||
104 | { | ||
105 | struct mmu_notifier *mn; | ||
106 | struct hlist_node *n; | ||
107 | |||
108 | rcu_read_lock(); | ||
109 | hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list, hlist) { | ||
110 | if (mn->ops->invalidate_page) | ||
111 | mn->ops->invalidate_page(mn, mm, address); | ||
112 | } | ||
113 | rcu_read_unlock(); | ||
114 | } | ||
115 | |||
116 | void __mmu_notifier_invalidate_range_start(struct mm_struct *mm, | ||
117 | unsigned long start, unsigned long end) | ||
118 | { | ||
119 | struct mmu_notifier *mn; | ||
120 | struct hlist_node *n; | ||
121 | |||
122 | rcu_read_lock(); | ||
123 | hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list, hlist) { | ||
124 | if (mn->ops->invalidate_range_start) | ||
125 | mn->ops->invalidate_range_start(mn, mm, start, end); | ||
126 | } | ||
127 | rcu_read_unlock(); | ||
128 | } | ||
129 | |||
130 | void __mmu_notifier_invalidate_range_end(struct mm_struct *mm, | ||
131 | unsigned long start, unsigned long end) | ||
132 | { | ||
133 | struct mmu_notifier *mn; | ||
134 | struct hlist_node *n; | ||
135 | |||
136 | rcu_read_lock(); | ||
137 | hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list, hlist) { | ||
138 | if (mn->ops->invalidate_range_end) | ||
139 | mn->ops->invalidate_range_end(mn, mm, start, end); | ||
140 | } | ||
141 | rcu_read_unlock(); | ||
142 | } | ||
143 | |||
144 | static int do_mmu_notifier_register(struct mmu_notifier *mn, | ||
145 | struct mm_struct *mm, | ||
146 | int take_mmap_sem) | ||
147 | { | ||
148 | struct mmu_notifier_mm *mmu_notifier_mm; | ||
149 | int ret; | ||
150 | |||
151 | BUG_ON(atomic_read(&mm->mm_users) <= 0); | ||
152 | |||
153 | ret = -ENOMEM; | ||
154 | mmu_notifier_mm = kmalloc(sizeof(struct mmu_notifier_mm), GFP_KERNEL); | ||
155 | if (unlikely(!mmu_notifier_mm)) | ||
156 | goto out; | ||
157 | |||
158 | if (take_mmap_sem) | ||
159 | down_write(&mm->mmap_sem); | ||
160 | ret = mm_take_all_locks(mm); | ||
161 | if (unlikely(ret)) | ||
162 | goto out_cleanup; | ||
163 | |||
164 | if (!mm_has_notifiers(mm)) { | ||
165 | INIT_HLIST_HEAD(&mmu_notifier_mm->list); | ||
166 | spin_lock_init(&mmu_notifier_mm->lock); | ||
167 | mm->mmu_notifier_mm = mmu_notifier_mm; | ||
168 | mmu_notifier_mm = NULL; | ||
169 | } | ||
170 | atomic_inc(&mm->mm_count); | ||
171 | |||
172 | /* | ||
173 | * Serialize the update against mmu_notifier_unregister. A | ||
174 | * side note: mmu_notifier_release can't run concurrently with | ||
175 | * us because we hold the mm_users pin (either implicitly as | ||
176 | * current->mm or explicitly with get_task_mm() or similar). | ||
177 | * We can't race against any other mmu notifier method either | ||
178 | * thanks to mm_take_all_locks(). | ||
179 | */ | ||
180 | spin_lock(&mm->mmu_notifier_mm->lock); | ||
181 | hlist_add_head(&mn->hlist, &mm->mmu_notifier_mm->list); | ||
182 | spin_unlock(&mm->mmu_notifier_mm->lock); | ||
183 | |||
184 | mm_drop_all_locks(mm); | ||
185 | out_cleanup: | ||
186 | if (take_mmap_sem) | ||
187 | up_write(&mm->mmap_sem); | ||
188 | /* kfree() does nothing if mmu_notifier_mm is NULL */ | ||
189 | kfree(mmu_notifier_mm); | ||
190 | out: | ||
191 | BUG_ON(atomic_read(&mm->mm_users) <= 0); | ||
192 | return ret; | ||
193 | } | ||
194 | |||
195 | /* | ||
196 | * Must not hold mmap_sem nor any other VM related lock when calling | ||
197 | * this registration function. Must also ensure mm_users can't go down | ||
198 | * to zero while this runs to avoid races with mmu_notifier_release, | ||
199 | * so mm has to be current->mm or the mm should be pinned safely such | ||
200 | * as with get_task_mm(). If the mm is not current->mm, the mm_users | ||
201 | * pin should be released by calling mmput after mmu_notifier_register | ||
202 | * returns. mmu_notifier_unregister must be always called to | ||
203 | * unregister the notifier. mm_count is automatically pinned to allow | ||
204 | * mmu_notifier_unregister to safely run at any time later, before or | ||
205 | * after exit_mmap. ->release will always be called before exit_mmap | ||
206 | * frees the pages. | ||
207 | */ | ||
208 | int mmu_notifier_register(struct mmu_notifier *mn, struct mm_struct *mm) | ||
209 | { | ||
210 | return do_mmu_notifier_register(mn, mm, 1); | ||
211 | } | ||
212 | EXPORT_SYMBOL_GPL(mmu_notifier_register); | ||
213 | |||
214 | /* | ||
215 | * Same as mmu_notifier_register but here the caller must hold the | ||
216 | * mmap_sem in write mode. | ||
217 | */ | ||
218 | int __mmu_notifier_register(struct mmu_notifier *mn, struct mm_struct *mm) | ||
219 | { | ||
220 | return do_mmu_notifier_register(mn, mm, 0); | ||
221 | } | ||
222 | EXPORT_SYMBOL_GPL(__mmu_notifier_register); | ||
223 | |||
224 | /* this is called after the last mmu_notifier_unregister() returned */ | ||
225 | void __mmu_notifier_mm_destroy(struct mm_struct *mm) | ||
226 | { | ||
227 | BUG_ON(!hlist_empty(&mm->mmu_notifier_mm->list)); | ||
228 | kfree(mm->mmu_notifier_mm); | ||
229 | mm->mmu_notifier_mm = LIST_POISON1; /* debug */ | ||
230 | } | ||
231 | |||
232 | /* | ||
233 | * This releases the mm_count pin automatically and frees the mm | ||
234 | * structure if it was the last user of it. It serializes against | ||
235 | * running mmu notifiers with RCU and against mmu_notifier_unregister | ||
236 | * with the unregister lock + RCU. All sptes must be dropped before | ||
237 | * calling mmu_notifier_unregister. ->release or any other notifier | ||
238 | * method may be invoked concurrently with mmu_notifier_unregister, | ||
239 | * and only after mmu_notifier_unregister returned we're guaranteed | ||
240 | * that ->release or any other method can't run anymore. | ||
241 | */ | ||
242 | void mmu_notifier_unregister(struct mmu_notifier *mn, struct mm_struct *mm) | ||
243 | { | ||
244 | BUG_ON(atomic_read(&mm->mm_count) <= 0); | ||
245 | |||
246 | spin_lock(&mm->mmu_notifier_mm->lock); | ||
247 | if (!hlist_unhashed(&mn->hlist)) { | ||
248 | hlist_del_rcu(&mn->hlist); | ||
249 | |||
250 | /* | ||
251 | * RCU here will force exit_mmap to wait ->release to finish | ||
252 | * before freeing the pages. | ||
253 | */ | ||
254 | rcu_read_lock(); | ||
255 | spin_unlock(&mm->mmu_notifier_mm->lock); | ||
256 | /* | ||
257 | * exit_mmap will block in mmu_notifier_release to | ||
258 | * guarantee ->release is called before freeing the | ||
259 | * pages. | ||
260 | */ | ||
261 | if (mn->ops->release) | ||
262 | mn->ops->release(mn, mm); | ||
263 | rcu_read_unlock(); | ||
264 | } else | ||
265 | spin_unlock(&mm->mmu_notifier_mm->lock); | ||
266 | |||
267 | /* | ||
268 | * Wait any running method to finish, of course including | ||
269 | * ->release if it was run by mmu_notifier_relase instead of us. | ||
270 | */ | ||
271 | synchronize_rcu(); | ||
272 | |||
273 | BUG_ON(atomic_read(&mm->mm_count) <= 0); | ||
274 | |||
275 | mmdrop(mm); | ||
276 | } | ||
277 | EXPORT_SYMBOL_GPL(mmu_notifier_unregister); | ||
diff --git a/mm/mprotect.c b/mm/mprotect.c index abd645a3b0a0..fded06f923f4 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/syscalls.h> | 21 | #include <linux/syscalls.h> |
22 | #include <linux/swap.h> | 22 | #include <linux/swap.h> |
23 | #include <linux/swapops.h> | 23 | #include <linux/swapops.h> |
24 | #include <linux/mmu_notifier.h> | ||
24 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
25 | #include <asm/pgtable.h> | 26 | #include <asm/pgtable.h> |
26 | #include <asm/cacheflush.h> | 27 | #include <asm/cacheflush.h> |
@@ -203,10 +204,12 @@ success: | |||
203 | dirty_accountable = 1; | 204 | dirty_accountable = 1; |
204 | } | 205 | } |
205 | 206 | ||
207 | mmu_notifier_invalidate_range_start(mm, start, end); | ||
206 | if (is_vm_hugetlb_page(vma)) | 208 | if (is_vm_hugetlb_page(vma)) |
207 | hugetlb_change_protection(vma, start, end, vma->vm_page_prot); | 209 | hugetlb_change_protection(vma, start, end, vma->vm_page_prot); |
208 | else | 210 | else |
209 | change_protection(vma, start, end, vma->vm_page_prot, dirty_accountable); | 211 | change_protection(vma, start, end, vma->vm_page_prot, dirty_accountable); |
212 | mmu_notifier_invalidate_range_end(mm, start, end); | ||
210 | vm_stat_account(mm, oldflags, vma->vm_file, -nrpages); | 213 | vm_stat_account(mm, oldflags, vma->vm_file, -nrpages); |
211 | vm_stat_account(mm, newflags, vma->vm_file, nrpages); | 214 | vm_stat_account(mm, newflags, vma->vm_file, nrpages); |
212 | return 0; | 215 | return 0; |
diff --git a/mm/mremap.c b/mm/mremap.c index 08e3c7f2bd15..1a7743923c8c 100644 --- a/mm/mremap.c +++ b/mm/mremap.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/highmem.h> | 18 | #include <linux/highmem.h> |
19 | #include <linux/security.h> | 19 | #include <linux/security.h> |
20 | #include <linux/syscalls.h> | 20 | #include <linux/syscalls.h> |
21 | #include <linux/mmu_notifier.h> | ||
21 | 22 | ||
22 | #include <asm/uaccess.h> | 23 | #include <asm/uaccess.h> |
23 | #include <asm/cacheflush.h> | 24 | #include <asm/cacheflush.h> |
@@ -74,7 +75,11 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd, | |||
74 | struct mm_struct *mm = vma->vm_mm; | 75 | struct mm_struct *mm = vma->vm_mm; |
75 | pte_t *old_pte, *new_pte, pte; | 76 | pte_t *old_pte, *new_pte, pte; |
76 | spinlock_t *old_ptl, *new_ptl; | 77 | spinlock_t *old_ptl, *new_ptl; |
78 | unsigned long old_start; | ||
77 | 79 | ||
80 | old_start = old_addr; | ||
81 | mmu_notifier_invalidate_range_start(vma->vm_mm, | ||
82 | old_start, old_end); | ||
78 | if (vma->vm_file) { | 83 | if (vma->vm_file) { |
79 | /* | 84 | /* |
80 | * Subtle point from Rajesh Venkatasubramanian: before | 85 | * Subtle point from Rajesh Venkatasubramanian: before |
@@ -116,6 +121,7 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd, | |||
116 | pte_unmap_unlock(old_pte - 1, old_ptl); | 121 | pte_unmap_unlock(old_pte - 1, old_ptl); |
117 | if (mapping) | 122 | if (mapping) |
118 | spin_unlock(&mapping->i_mmap_lock); | 123 | spin_unlock(&mapping->i_mmap_lock); |
124 | mmu_notifier_invalidate_range_end(vma->vm_mm, old_start, old_end); | ||
119 | } | 125 | } |
120 | 126 | ||
121 | #define LATENCY_LIMIT (64 * PAGE_SIZE) | 127 | #define LATENCY_LIMIT (64 * PAGE_SIZE) |
diff --git a/mm/nommu.c b/mm/nommu.c index 5edccd9c9218..ed75bc962fbe 100644 --- a/mm/nommu.c +++ b/mm/nommu.c | |||
@@ -266,6 +266,27 @@ void *vmalloc_node(unsigned long size, int node) | |||
266 | } | 266 | } |
267 | EXPORT_SYMBOL(vmalloc_node); | 267 | EXPORT_SYMBOL(vmalloc_node); |
268 | 268 | ||
269 | #ifndef PAGE_KERNEL_EXEC | ||
270 | # define PAGE_KERNEL_EXEC PAGE_KERNEL | ||
271 | #endif | ||
272 | |||
273 | /** | ||
274 | * vmalloc_exec - allocate virtually contiguous, executable memory | ||
275 | * @size: allocation size | ||
276 | * | ||
277 | * Kernel-internal function to allocate enough pages to cover @size | ||
278 | * the page level allocator and map them into contiguous and | ||
279 | * executable kernel virtual space. | ||
280 | * | ||
281 | * For tight control over page level allocator and protection flags | ||
282 | * use __vmalloc() instead. | ||
283 | */ | ||
284 | |||
285 | void *vmalloc_exec(unsigned long size) | ||
286 | { | ||
287 | return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC); | ||
288 | } | ||
289 | |||
269 | /** | 290 | /** |
270 | * vmalloc_32 - allocate virtually contiguous memory (32bit addressable) | 291 | * vmalloc_32 - allocate virtually contiguous memory (32bit addressable) |
271 | * @size: allocation size | 292 | * @size: allocation size |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 6da667274df5..af982f7cdb2a 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -2372,7 +2372,7 @@ static void build_zonelist_cache(pg_data_t *pgdat) | |||
2372 | 2372 | ||
2373 | #endif /* CONFIG_NUMA */ | 2373 | #endif /* CONFIG_NUMA */ |
2374 | 2374 | ||
2375 | /* return values int ....just for stop_machine_run() */ | 2375 | /* return values int ....just for stop_machine() */ |
2376 | static int __build_all_zonelists(void *dummy) | 2376 | static int __build_all_zonelists(void *dummy) |
2377 | { | 2377 | { |
2378 | int nid; | 2378 | int nid; |
@@ -2397,7 +2397,7 @@ void build_all_zonelists(void) | |||
2397 | } else { | 2397 | } else { |
2398 | /* we have to stop all cpus to guarantee there is no user | 2398 | /* we have to stop all cpus to guarantee there is no user |
2399 | of zonelist */ | 2399 | of zonelist */ |
2400 | stop_machine_run(__build_all_zonelists, NULL, NR_CPUS); | 2400 | stop_machine(__build_all_zonelists, NULL, NULL); |
2401 | /* cpuset refresh routine should be here */ | 2401 | /* cpuset refresh routine should be here */ |
2402 | } | 2402 | } |
2403 | vm_total_pages = nr_free_pagecache_pages(); | 2403 | vm_total_pages = nr_free_pagecache_pages(); |
@@ -3753,23 +3753,6 @@ unsigned long __init find_min_pfn_with_active_regions(void) | |||
3753 | return find_min_pfn_for_node(MAX_NUMNODES); | 3753 | return find_min_pfn_for_node(MAX_NUMNODES); |
3754 | } | 3754 | } |
3755 | 3755 | ||
3756 | /** | ||
3757 | * find_max_pfn_with_active_regions - Find the maximum PFN registered | ||
3758 | * | ||
3759 | * It returns the maximum PFN based on information provided via | ||
3760 | * add_active_range(). | ||
3761 | */ | ||
3762 | unsigned long __init find_max_pfn_with_active_regions(void) | ||
3763 | { | ||
3764 | int i; | ||
3765 | unsigned long max_pfn = 0; | ||
3766 | |||
3767 | for (i = 0; i < nr_nodemap_entries; i++) | ||
3768 | max_pfn = max(max_pfn, early_node_map[i].end_pfn); | ||
3769 | |||
3770 | return max_pfn; | ||
3771 | } | ||
3772 | |||
3773 | /* | 3756 | /* |
3774 | * early_calculate_totalpages() | 3757 | * early_calculate_totalpages() |
3775 | * Sum pages in active regions for movable zone. | 3758 | * Sum pages in active regions for movable zone. |
@@ -4454,7 +4437,7 @@ void *__init alloc_large_system_hash(const char *tablename, | |||
4454 | do { | 4437 | do { |
4455 | size = bucketsize << log2qty; | 4438 | size = bucketsize << log2qty; |
4456 | if (flags & HASH_EARLY) | 4439 | if (flags & HASH_EARLY) |
4457 | table = alloc_bootmem(size); | 4440 | table = alloc_bootmem_nopanic(size); |
4458 | else if (hashdist) | 4441 | else if (hashdist) |
4459 | table = __vmalloc(size, GFP_ATOMIC, PAGE_KERNEL); | 4442 | table = __vmalloc(size, GFP_ATOMIC, PAGE_KERNEL); |
4460 | else { | 4443 | else { |
@@ -49,6 +49,7 @@ | |||
49 | #include <linux/module.h> | 49 | #include <linux/module.h> |
50 | #include <linux/kallsyms.h> | 50 | #include <linux/kallsyms.h> |
51 | #include <linux/memcontrol.h> | 51 | #include <linux/memcontrol.h> |
52 | #include <linux/mmu_notifier.h> | ||
52 | 53 | ||
53 | #include <asm/tlbflush.h> | 54 | #include <asm/tlbflush.h> |
54 | 55 | ||
@@ -287,7 +288,7 @@ static int page_referenced_one(struct page *page, | |||
287 | if (vma->vm_flags & VM_LOCKED) { | 288 | if (vma->vm_flags & VM_LOCKED) { |
288 | referenced++; | 289 | referenced++; |
289 | *mapcount = 1; /* break early from loop */ | 290 | *mapcount = 1; /* break early from loop */ |
290 | } else if (ptep_clear_flush_young(vma, address, pte)) | 291 | } else if (ptep_clear_flush_young_notify(vma, address, pte)) |
291 | referenced++; | 292 | referenced++; |
292 | 293 | ||
293 | /* Pretend the page is referenced if the task has the | 294 | /* Pretend the page is referenced if the task has the |
@@ -421,7 +422,7 @@ int page_referenced(struct page *page, int is_locked, | |||
421 | referenced += page_referenced_anon(page, mem_cont); | 422 | referenced += page_referenced_anon(page, mem_cont); |
422 | else if (is_locked) | 423 | else if (is_locked) |
423 | referenced += page_referenced_file(page, mem_cont); | 424 | referenced += page_referenced_file(page, mem_cont); |
424 | else if (TestSetPageLocked(page)) | 425 | else if (!trylock_page(page)) |
425 | referenced++; | 426 | referenced++; |
426 | else { | 427 | else { |
427 | if (page->mapping) | 428 | if (page->mapping) |
@@ -457,7 +458,7 @@ static int page_mkclean_one(struct page *page, struct vm_area_struct *vma) | |||
457 | pte_t entry; | 458 | pte_t entry; |
458 | 459 | ||
459 | flush_cache_page(vma, address, pte_pfn(*pte)); | 460 | flush_cache_page(vma, address, pte_pfn(*pte)); |
460 | entry = ptep_clear_flush(vma, address, pte); | 461 | entry = ptep_clear_flush_notify(vma, address, pte); |
461 | entry = pte_wrprotect(entry); | 462 | entry = pte_wrprotect(entry); |
462 | entry = pte_mkclean(entry); | 463 | entry = pte_mkclean(entry); |
463 | set_pte_at(mm, address, pte, entry); | 464 | set_pte_at(mm, address, pte, entry); |
@@ -666,7 +667,8 @@ void page_remove_rmap(struct page *page, struct vm_area_struct *vma) | |||
666 | * Leaving it set also helps swapoff to reinstate ptes | 667 | * Leaving it set also helps swapoff to reinstate ptes |
667 | * faster for those pages still in swapcache. | 668 | * faster for those pages still in swapcache. |
668 | */ | 669 | */ |
669 | if (page_test_dirty(page)) { | 670 | if ((!PageAnon(page) || PageSwapCache(page)) && |
671 | page_test_dirty(page)) { | ||
670 | page_clear_dirty(page); | 672 | page_clear_dirty(page); |
671 | set_page_dirty(page); | 673 | set_page_dirty(page); |
672 | } | 674 | } |
@@ -705,14 +707,14 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma, | |||
705 | * skipped over this mm) then we should reactivate it. | 707 | * skipped over this mm) then we should reactivate it. |
706 | */ | 708 | */ |
707 | if (!migration && ((vma->vm_flags & VM_LOCKED) || | 709 | if (!migration && ((vma->vm_flags & VM_LOCKED) || |
708 | (ptep_clear_flush_young(vma, address, pte)))) { | 710 | (ptep_clear_flush_young_notify(vma, address, pte)))) { |
709 | ret = SWAP_FAIL; | 711 | ret = SWAP_FAIL; |
710 | goto out_unmap; | 712 | goto out_unmap; |
711 | } | 713 | } |
712 | 714 | ||
713 | /* Nuke the page table entry. */ | 715 | /* Nuke the page table entry. */ |
714 | flush_cache_page(vma, address, page_to_pfn(page)); | 716 | flush_cache_page(vma, address, page_to_pfn(page)); |
715 | pteval = ptep_clear_flush(vma, address, pte); | 717 | pteval = ptep_clear_flush_notify(vma, address, pte); |
716 | 718 | ||
717 | /* Move the dirty bit to the physical page now the pte is gone. */ | 719 | /* Move the dirty bit to the physical page now the pte is gone. */ |
718 | if (pte_dirty(pteval)) | 720 | if (pte_dirty(pteval)) |
@@ -837,12 +839,12 @@ static void try_to_unmap_cluster(unsigned long cursor, | |||
837 | page = vm_normal_page(vma, address, *pte); | 839 | page = vm_normal_page(vma, address, *pte); |
838 | BUG_ON(!page || PageAnon(page)); | 840 | BUG_ON(!page || PageAnon(page)); |
839 | 841 | ||
840 | if (ptep_clear_flush_young(vma, address, pte)) | 842 | if (ptep_clear_flush_young_notify(vma, address, pte)) |
841 | continue; | 843 | continue; |
842 | 844 | ||
843 | /* Nuke the page table entry. */ | 845 | /* Nuke the page table entry. */ |
844 | flush_cache_page(vma, address, pte_pfn(*pte)); | 846 | flush_cache_page(vma, address, pte_pfn(*pte)); |
845 | pteval = ptep_clear_flush(vma, address, pte); | 847 | pteval = ptep_clear_flush_notify(vma, address, pte); |
846 | 848 | ||
847 | /* If nonlinear, store the file page offset in the pte. */ | 849 | /* If nonlinear, store the file page offset in the pte. */ |
848 | if (page->index != linear_page_index(vma, address)) | 850 | if (page->index != linear_page_index(vma, address)) |
diff --git a/mm/shmem.c b/mm/shmem.c index 952d361774bb..04fb4f1ab88e 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -1265,7 +1265,7 @@ repeat: | |||
1265 | } | 1265 | } |
1266 | 1266 | ||
1267 | /* We have to do this with page locked to prevent races */ | 1267 | /* We have to do this with page locked to prevent races */ |
1268 | if (TestSetPageLocked(swappage)) { | 1268 | if (!trylock_page(swappage)) { |
1269 | shmem_swp_unmap(entry); | 1269 | shmem_swp_unmap(entry); |
1270 | spin_unlock(&info->lock); | 1270 | spin_unlock(&info->lock); |
1271 | wait_on_page_locked(swappage); | 1271 | wait_on_page_locked(swappage); |
@@ -1329,7 +1329,7 @@ repeat: | |||
1329 | shmem_swp_unmap(entry); | 1329 | shmem_swp_unmap(entry); |
1330 | filepage = find_get_page(mapping, idx); | 1330 | filepage = find_get_page(mapping, idx); |
1331 | if (filepage && | 1331 | if (filepage && |
1332 | (!PageUptodate(filepage) || TestSetPageLocked(filepage))) { | 1332 | (!PageUptodate(filepage) || !trylock_page(filepage))) { |
1333 | spin_unlock(&info->lock); | 1333 | spin_unlock(&info->lock); |
1334 | wait_on_page_locked(filepage); | 1334 | wait_on_page_locked(filepage); |
1335 | page_cache_release(filepage); | 1335 | page_cache_release(filepage); |
@@ -1513,7 +1513,6 @@ shmem_get_inode(struct super_block *sb, int mode, dev_t dev) | |||
1513 | inode->i_uid = current->fsuid; | 1513 | inode->i_uid = current->fsuid; |
1514 | inode->i_gid = current->fsgid; | 1514 | inode->i_gid = current->fsgid; |
1515 | inode->i_blocks = 0; | 1515 | inode->i_blocks = 0; |
1516 | inode->i_mapping->a_ops = &shmem_aops; | ||
1517 | inode->i_mapping->backing_dev_info = &shmem_backing_dev_info; | 1516 | inode->i_mapping->backing_dev_info = &shmem_backing_dev_info; |
1518 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 1517 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
1519 | inode->i_generation = get_seconds(); | 1518 | inode->i_generation = get_seconds(); |
@@ -1528,6 +1527,7 @@ shmem_get_inode(struct super_block *sb, int mode, dev_t dev) | |||
1528 | init_special_inode(inode, mode, dev); | 1527 | init_special_inode(inode, mode, dev); |
1529 | break; | 1528 | break; |
1530 | case S_IFREG: | 1529 | case S_IFREG: |
1530 | inode->i_mapping->a_ops = &shmem_aops; | ||
1531 | inode->i_op = &shmem_inode_operations; | 1531 | inode->i_op = &shmem_inode_operations; |
1532 | inode->i_fop = &shmem_file_operations; | 1532 | inode->i_fop = &shmem_file_operations; |
1533 | mpol_shared_policy_init(&info->policy, | 1533 | mpol_shared_policy_init(&info->policy, |
@@ -1929,6 +1929,7 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s | |||
1929 | return error; | 1929 | return error; |
1930 | } | 1930 | } |
1931 | unlock_page(page); | 1931 | unlock_page(page); |
1932 | inode->i_mapping->a_ops = &shmem_aops; | ||
1932 | inode->i_op = &shmem_symlink_inode_operations; | 1933 | inode->i_op = &shmem_symlink_inode_operations; |
1933 | kaddr = kmap_atomic(page, KM_USER0); | 1934 | kaddr = kmap_atomic(page, KM_USER0); |
1934 | memcpy(kaddr, symname, len); | 1935 | memcpy(kaddr, symname, len); |
@@ -4472,4 +4472,3 @@ size_t ksize(const void *objp) | |||
4472 | 4472 | ||
4473 | return obj_size(virt_to_cache(objp)); | 4473 | return obj_size(virt_to_cache(objp)); |
4474 | } | 4474 | } |
4475 | EXPORT_SYMBOL(ksize); | ||
@@ -519,7 +519,6 @@ size_t ksize(const void *block) | |||
519 | else | 519 | else |
520 | return sp->page.private; | 520 | return sp->page.private; |
521 | } | 521 | } |
522 | EXPORT_SYMBOL(ksize); | ||
523 | 522 | ||
524 | struct kmem_cache { | 523 | struct kmem_cache { |
525 | unsigned int size, align; | 524 | unsigned int size, align; |
@@ -1329,7 +1329,7 @@ static struct page *get_any_partial(struct kmem_cache *s, gfp_t flags) | |||
1329 | n = get_node(s, zone_to_nid(zone)); | 1329 | n = get_node(s, zone_to_nid(zone)); |
1330 | 1330 | ||
1331 | if (n && cpuset_zone_allowed_hardwall(zone, flags) && | 1331 | if (n && cpuset_zone_allowed_hardwall(zone, flags) && |
1332 | n->nr_partial > MIN_PARTIAL) { | 1332 | n->nr_partial > n->min_partial) { |
1333 | page = get_partial_node(n); | 1333 | page = get_partial_node(n); |
1334 | if (page) | 1334 | if (page) |
1335 | return page; | 1335 | return page; |
@@ -1381,7 +1381,7 @@ static void unfreeze_slab(struct kmem_cache *s, struct page *page, int tail) | |||
1381 | slab_unlock(page); | 1381 | slab_unlock(page); |
1382 | } else { | 1382 | } else { |
1383 | stat(c, DEACTIVATE_EMPTY); | 1383 | stat(c, DEACTIVATE_EMPTY); |
1384 | if (n->nr_partial < MIN_PARTIAL) { | 1384 | if (n->nr_partial < n->min_partial) { |
1385 | /* | 1385 | /* |
1386 | * Adding an empty slab to the partial slabs in order | 1386 | * Adding an empty slab to the partial slabs in order |
1387 | * to avoid page allocator overhead. This slab needs | 1387 | * to avoid page allocator overhead. This slab needs |
@@ -1913,9 +1913,21 @@ static void init_kmem_cache_cpu(struct kmem_cache *s, | |||
1913 | #endif | 1913 | #endif |
1914 | } | 1914 | } |
1915 | 1915 | ||
1916 | static void init_kmem_cache_node(struct kmem_cache_node *n) | 1916 | static void |
1917 | init_kmem_cache_node(struct kmem_cache_node *n, struct kmem_cache *s) | ||
1917 | { | 1918 | { |
1918 | n->nr_partial = 0; | 1919 | n->nr_partial = 0; |
1920 | |||
1921 | /* | ||
1922 | * The larger the object size is, the more pages we want on the partial | ||
1923 | * list to avoid pounding the page allocator excessively. | ||
1924 | */ | ||
1925 | n->min_partial = ilog2(s->size); | ||
1926 | if (n->min_partial < MIN_PARTIAL) | ||
1927 | n->min_partial = MIN_PARTIAL; | ||
1928 | else if (n->min_partial > MAX_PARTIAL) | ||
1929 | n->min_partial = MAX_PARTIAL; | ||
1930 | |||
1919 | spin_lock_init(&n->list_lock); | 1931 | spin_lock_init(&n->list_lock); |
1920 | INIT_LIST_HEAD(&n->partial); | 1932 | INIT_LIST_HEAD(&n->partial); |
1921 | #ifdef CONFIG_SLUB_DEBUG | 1933 | #ifdef CONFIG_SLUB_DEBUG |
@@ -2087,7 +2099,7 @@ static struct kmem_cache_node *early_kmem_cache_node_alloc(gfp_t gfpflags, | |||
2087 | init_object(kmalloc_caches, n, 1); | 2099 | init_object(kmalloc_caches, n, 1); |
2088 | init_tracking(kmalloc_caches, n); | 2100 | init_tracking(kmalloc_caches, n); |
2089 | #endif | 2101 | #endif |
2090 | init_kmem_cache_node(n); | 2102 | init_kmem_cache_node(n, kmalloc_caches); |
2091 | inc_slabs_node(kmalloc_caches, node, page->objects); | 2103 | inc_slabs_node(kmalloc_caches, node, page->objects); |
2092 | 2104 | ||
2093 | /* | 2105 | /* |
@@ -2144,7 +2156,7 @@ static int init_kmem_cache_nodes(struct kmem_cache *s, gfp_t gfpflags) | |||
2144 | 2156 | ||
2145 | } | 2157 | } |
2146 | s->node[node] = n; | 2158 | s->node[node] = n; |
2147 | init_kmem_cache_node(n); | 2159 | init_kmem_cache_node(n, s); |
2148 | } | 2160 | } |
2149 | return 1; | 2161 | return 1; |
2150 | } | 2162 | } |
@@ -2155,7 +2167,7 @@ static void free_kmem_cache_nodes(struct kmem_cache *s) | |||
2155 | 2167 | ||
2156 | static int init_kmem_cache_nodes(struct kmem_cache *s, gfp_t gfpflags) | 2168 | static int init_kmem_cache_nodes(struct kmem_cache *s, gfp_t gfpflags) |
2157 | { | 2169 | { |
2158 | init_kmem_cache_node(&s->local_node); | 2170 | init_kmem_cache_node(&s->local_node, s); |
2159 | return 1; | 2171 | return 1; |
2160 | } | 2172 | } |
2161 | #endif | 2173 | #endif |
@@ -2715,7 +2727,6 @@ size_t ksize(const void *object) | |||
2715 | */ | 2727 | */ |
2716 | return s->size; | 2728 | return s->size; |
2717 | } | 2729 | } |
2718 | EXPORT_SYMBOL(ksize); | ||
2719 | 2730 | ||
2720 | void kfree(const void *x) | 2731 | void kfree(const void *x) |
2721 | { | 2732 | { |
@@ -2890,7 +2901,7 @@ static int slab_mem_going_online_callback(void *arg) | |||
2890 | ret = -ENOMEM; | 2901 | ret = -ENOMEM; |
2891 | goto out; | 2902 | goto out; |
2892 | } | 2903 | } |
2893 | init_kmem_cache_node(n); | 2904 | init_kmem_cache_node(n, s); |
2894 | s->node[nid] = n; | 2905 | s->node[nid] = n; |
2895 | } | 2906 | } |
2896 | out: | 2907 | out: |
diff --git a/mm/sparse.c b/mm/sparse.c index 5d9dbbb9d39e..39db301b920d 100644 --- a/mm/sparse.c +++ b/mm/sparse.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <asm/dma.h> | 12 | #include <asm/dma.h> |
13 | #include <asm/pgalloc.h> | 13 | #include <asm/pgalloc.h> |
14 | #include <asm/pgtable.h> | 14 | #include <asm/pgtable.h> |
15 | #include "internal.h" | ||
16 | 15 | ||
17 | /* | 16 | /* |
18 | * Permanent SPARSEMEM data: | 17 | * Permanent SPARSEMEM data: |
@@ -278,9 +278,10 @@ int lru_add_drain_all(void) | |||
278 | * Avoid taking zone->lru_lock if possible, but if it is taken, retain it | 278 | * Avoid taking zone->lru_lock if possible, but if it is taken, retain it |
279 | * for the remainder of the operation. | 279 | * for the remainder of the operation. |
280 | * | 280 | * |
281 | * The locking in this function is against shrink_cache(): we recheck the | 281 | * The locking in this function is against shrink_inactive_list(): we recheck |
282 | * page count inside the lock to see whether shrink_cache grabbed the page | 282 | * the page count inside the lock to see whether shrink_inactive_list() |
283 | * via the LRU. If it did, give up: shrink_cache will free it. | 283 | * grabbed the page via the LRU. If it did, give up: shrink_inactive_list() |
284 | * will free it. | ||
284 | */ | 285 | */ |
285 | void release_pages(struct page **pages, int nr, int cold) | 286 | void release_pages(struct page **pages, int nr, int cold) |
286 | { | 287 | { |
@@ -443,7 +444,7 @@ void pagevec_strip(struct pagevec *pvec) | |||
443 | for (i = 0; i < pagevec_count(pvec); i++) { | 444 | for (i = 0; i < pagevec_count(pvec); i++) { |
444 | struct page *page = pvec->pages[i]; | 445 | struct page *page = pvec->pages[i]; |
445 | 446 | ||
446 | if (PagePrivate(page) && !TestSetPageLocked(page)) { | 447 | if (PagePrivate(page) && trylock_page(page)) { |
447 | if (PagePrivate(page)) | 448 | if (PagePrivate(page)) |
448 | try_to_release_page(page, 0); | 449 | try_to_release_page(page, 0); |
449 | unlock_page(page); | 450 | unlock_page(page); |
diff --git a/mm/swap_state.c b/mm/swap_state.c index b8035b055129..167cf2dc8a03 100644 --- a/mm/swap_state.c +++ b/mm/swap_state.c | |||
@@ -201,7 +201,7 @@ void delete_from_swap_cache(struct page *page) | |||
201 | */ | 201 | */ |
202 | static inline void free_swap_cache(struct page *page) | 202 | static inline void free_swap_cache(struct page *page) |
203 | { | 203 | { |
204 | if (PageSwapCache(page) && !TestSetPageLocked(page)) { | 204 | if (PageSwapCache(page) && trylock_page(page)) { |
205 | remove_exclusive_swap_page(page); | 205 | remove_exclusive_swap_page(page); |
206 | unlock_page(page); | 206 | unlock_page(page); |
207 | } | 207 | } |
@@ -302,9 +302,9 @@ struct page *read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask, | |||
302 | * re-using the just freed swap entry for an existing page. | 302 | * re-using the just freed swap entry for an existing page. |
303 | * May fail (-ENOMEM) if radix-tree node allocation failed. | 303 | * May fail (-ENOMEM) if radix-tree node allocation failed. |
304 | */ | 304 | */ |
305 | SetPageLocked(new_page); | 305 | set_page_locked(new_page); |
306 | err = add_to_swap_cache(new_page, entry, gfp_mask & GFP_KERNEL); | 306 | err = add_to_swap_cache(new_page, entry, gfp_mask & GFP_KERNEL); |
307 | if (!err) { | 307 | if (likely(!err)) { |
308 | /* | 308 | /* |
309 | * Initiate read into locked page and return. | 309 | * Initiate read into locked page and return. |
310 | */ | 310 | */ |
@@ -312,7 +312,7 @@ struct page *read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask, | |||
312 | swap_readpage(NULL, new_page); | 312 | swap_readpage(NULL, new_page); |
313 | return new_page; | 313 | return new_page; |
314 | } | 314 | } |
315 | ClearPageLocked(new_page); | 315 | clear_page_locked(new_page); |
316 | swap_free(entry); | 316 | swap_free(entry); |
317 | } while (err != -ENOMEM); | 317 | } while (err != -ENOMEM); |
318 | 318 | ||
diff --git a/mm/swapfile.c b/mm/swapfile.c index 6beb6251e99d..1e330f2998fa 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c | |||
@@ -403,7 +403,7 @@ void free_swap_and_cache(swp_entry_t entry) | |||
403 | if (p) { | 403 | if (p) { |
404 | if (swap_entry_free(p, swp_offset(entry)) == 1) { | 404 | if (swap_entry_free(p, swp_offset(entry)) == 1) { |
405 | page = find_get_page(&swapper_space, entry.val); | 405 | page = find_get_page(&swapper_space, entry.val); |
406 | if (page && unlikely(TestSetPageLocked(page))) { | 406 | if (page && unlikely(!trylock_page(page))) { |
407 | page_cache_release(page); | 407 | page_cache_release(page); |
408 | page = NULL; | 408 | page = NULL; |
409 | } | 409 | } |
@@ -656,8 +656,8 @@ static int unuse_mm(struct mm_struct *mm, | |||
656 | 656 | ||
657 | if (!down_read_trylock(&mm->mmap_sem)) { | 657 | if (!down_read_trylock(&mm->mmap_sem)) { |
658 | /* | 658 | /* |
659 | * Activate page so shrink_cache is unlikely to unmap its | 659 | * Activate page so shrink_inactive_list is unlikely to unmap |
660 | * ptes while lock is dropped, so swapoff can make progress. | 660 | * its ptes while lock is dropped, so swapoff can make progress. |
661 | */ | 661 | */ |
662 | activate_page(page); | 662 | activate_page(page); |
663 | unlock_page(page); | 663 | unlock_page(page); |
diff --git a/mm/truncate.c b/mm/truncate.c index e68443d74567..250505091d37 100644 --- a/mm/truncate.c +++ b/mm/truncate.c | |||
@@ -104,7 +104,6 @@ truncate_complete_page(struct address_space *mapping, struct page *page) | |||
104 | cancel_dirty_page(page, PAGE_CACHE_SIZE); | 104 | cancel_dirty_page(page, PAGE_CACHE_SIZE); |
105 | 105 | ||
106 | remove_from_page_cache(page); | 106 | remove_from_page_cache(page); |
107 | ClearPageUptodate(page); | ||
108 | ClearPageMappedToDisk(page); | 107 | ClearPageMappedToDisk(page); |
109 | page_cache_release(page); /* pagecache ref */ | 108 | page_cache_release(page); /* pagecache ref */ |
110 | } | 109 | } |
@@ -188,7 +187,7 @@ void truncate_inode_pages_range(struct address_space *mapping, | |||
188 | if (page_index > next) | 187 | if (page_index > next) |
189 | next = page_index; | 188 | next = page_index; |
190 | next++; | 189 | next++; |
191 | if (TestSetPageLocked(page)) | 190 | if (!trylock_page(page)) |
192 | continue; | 191 | continue; |
193 | if (PageWriteback(page)) { | 192 | if (PageWriteback(page)) { |
194 | unlock_page(page); | 193 | unlock_page(page); |
@@ -281,7 +280,7 @@ unsigned long __invalidate_mapping_pages(struct address_space *mapping, | |||
281 | pgoff_t index; | 280 | pgoff_t index; |
282 | int lock_failed; | 281 | int lock_failed; |
283 | 282 | ||
284 | lock_failed = TestSetPageLocked(page); | 283 | lock_failed = !trylock_page(page); |
285 | 284 | ||
286 | /* | 285 | /* |
287 | * We really shouldn't be looking at the ->index of an | 286 | * We really shouldn't be looking at the ->index of an |
@@ -356,7 +355,6 @@ invalidate_complete_page2(struct address_space *mapping, struct page *page) | |||
356 | BUG_ON(PagePrivate(page)); | 355 | BUG_ON(PagePrivate(page)); |
357 | __remove_from_page_cache(page); | 356 | __remove_from_page_cache(page); |
358 | spin_unlock_irq(&mapping->tree_lock); | 357 | spin_unlock_irq(&mapping->tree_lock); |
359 | ClearPageUptodate(page); | ||
360 | page_cache_release(page); /* pagecache ref */ | 358 | page_cache_release(page); /* pagecache ref */ |
361 | return 1; | 359 | return 1; |
362 | failed: | 360 | failed: |
@@ -171,3 +171,18 @@ void arch_pick_mmap_layout(struct mm_struct *mm) | |||
171 | mm->unmap_area = arch_unmap_area; | 171 | mm->unmap_area = arch_unmap_area; |
172 | } | 172 | } |
173 | #endif | 173 | #endif |
174 | |||
175 | int __attribute__((weak)) get_user_pages_fast(unsigned long start, | ||
176 | int nr_pages, int write, struct page **pages) | ||
177 | { | ||
178 | struct mm_struct *mm = current->mm; | ||
179 | int ret; | ||
180 | |||
181 | down_read(&mm->mmap_sem); | ||
182 | ret = get_user_pages(current, mm, start, nr_pages, | ||
183 | write, 0, pages, NULL); | ||
184 | up_read(&mm->mmap_sem); | ||
185 | |||
186 | return ret; | ||
187 | } | ||
188 | EXPORT_SYMBOL_GPL(get_user_pages_fast); | ||
diff --git a/mm/vmscan.c b/mm/vmscan.c index 8f71761bc4b7..1ff1a58e7c10 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -496,7 +496,7 @@ static unsigned long shrink_page_list(struct list_head *page_list, | |||
496 | page = lru_to_page(page_list); | 496 | page = lru_to_page(page_list); |
497 | list_del(&page->lru); | 497 | list_del(&page->lru); |
498 | 498 | ||
499 | if (TestSetPageLocked(page)) | 499 | if (!trylock_page(page)) |
500 | goto keep; | 500 | goto keep; |
501 | 501 | ||
502 | VM_BUG_ON(PageActive(page)); | 502 | VM_BUG_ON(PageActive(page)); |
@@ -582,7 +582,7 @@ static unsigned long shrink_page_list(struct list_head *page_list, | |||
582 | * A synchronous write - probably a ramdisk. Go | 582 | * A synchronous write - probably a ramdisk. Go |
583 | * ahead and try to reclaim the page. | 583 | * ahead and try to reclaim the page. |
584 | */ | 584 | */ |
585 | if (TestSetPageLocked(page)) | 585 | if (!trylock_page(page)) |
586 | goto keep; | 586 | goto keep; |
587 | if (PageDirty(page) || PageWriteback(page)) | 587 | if (PageDirty(page) || PageWriteback(page)) |
588 | goto keep_locked; | 588 | goto keep_locked; |
@@ -1408,7 +1408,7 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, | |||
1408 | if (sc->nr_scanned && priority < DEF_PRIORITY - 2) | 1408 | if (sc->nr_scanned && priority < DEF_PRIORITY - 2) |
1409 | congestion_wait(WRITE, HZ/10); | 1409 | congestion_wait(WRITE, HZ/10); |
1410 | } | 1410 | } |
1411 | /* top priority shrink_caches still had more to do? don't OOM, then */ | 1411 | /* top priority shrink_zones still had more to do? don't OOM, then */ |
1412 | if (!sc->all_unreclaimable && scan_global_lru(sc)) | 1412 | if (!sc->all_unreclaimable && scan_global_lru(sc)) |
1413 | ret = nr_reclaimed; | 1413 | ret = nr_reclaimed; |
1414 | out: | 1414 | out: |
@@ -1979,7 +1979,7 @@ module_init(kswapd_init) | |||
1979 | int zone_reclaim_mode __read_mostly; | 1979 | int zone_reclaim_mode __read_mostly; |
1980 | 1980 | ||
1981 | #define RECLAIM_OFF 0 | 1981 | #define RECLAIM_OFF 0 |
1982 | #define RECLAIM_ZONE (1<<0) /* Run shrink_cache on the zone */ | 1982 | #define RECLAIM_ZONE (1<<0) /* Run shrink_inactive_list on the zone */ |
1983 | #define RECLAIM_WRITE (1<<1) /* Writeout pages during reclaim */ | 1983 | #define RECLAIM_WRITE (1<<1) /* Writeout pages during reclaim */ |
1984 | #define RECLAIM_SWAP (1<<2) /* Swap pages out during reclaim */ | 1984 | #define RECLAIM_SWAP (1<<2) /* Swap pages out during reclaim */ |
1985 | 1985 | ||