diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/gup.c | 81 | ||||
-rw-r--r-- | mm/huge_memory.c | 5 | ||||
-rw-r--r-- | mm/hugetlb.c | 2 | ||||
-rw-r--r-- | mm/memory.c | 2 | ||||
-rw-r--r-- | mm/oom_kill.c | 2 | ||||
-rw-r--r-- | mm/page_alloc.c | 6 | ||||
-rw-r--r-- | mm/percpu.c | 2 | ||||
-rw-r--r-- | mm/slab.c | 2 | ||||
-rw-r--r-- | mm/slub.c | 3 | ||||
-rw-r--r-- | mm/vmscan.c | 5 | ||||
-rw-r--r-- | mm/zbud.c | 2 | ||||
-rw-r--r-- | mm/zswap.c | 2 |
12 files changed, 91 insertions, 23 deletions
@@ -3,7 +3,6 @@ | |||
3 | #include <linux/err.h> | 3 | #include <linux/err.h> |
4 | #include <linux/spinlock.h> | 4 | #include <linux/spinlock.h> |
5 | 5 | ||
6 | #include <linux/hugetlb.h> | ||
7 | #include <linux/mm.h> | 6 | #include <linux/mm.h> |
8 | #include <linux/pagemap.h> | 7 | #include <linux/pagemap.h> |
9 | #include <linux/rmap.h> | 8 | #include <linux/rmap.h> |
@@ -12,6 +11,7 @@ | |||
12 | 11 | ||
13 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
14 | #include <linux/rwsem.h> | 13 | #include <linux/rwsem.h> |
14 | #include <linux/hugetlb.h> | ||
15 | #include <asm/pgtable.h> | 15 | #include <asm/pgtable.h> |
16 | 16 | ||
17 | #include "internal.h" | 17 | #include "internal.h" |
@@ -875,6 +875,49 @@ static int gup_huge_pud(pud_t orig, pud_t *pudp, unsigned long addr, | |||
875 | return 1; | 875 | return 1; |
876 | } | 876 | } |
877 | 877 | ||
878 | static int gup_huge_pgd(pgd_t orig, pgd_t *pgdp, unsigned long addr, | ||
879 | unsigned long end, int write, | ||
880 | struct page **pages, int *nr) | ||
881 | { | ||
882 | int refs; | ||
883 | struct page *head, *page, *tail; | ||
884 | |||
885 | if (write && !pgd_write(orig)) | ||
886 | return 0; | ||
887 | |||
888 | refs = 0; | ||
889 | head = pgd_page(orig); | ||
890 | page = head + ((addr & ~PGDIR_MASK) >> PAGE_SHIFT); | ||
891 | tail = page; | ||
892 | do { | ||
893 | VM_BUG_ON_PAGE(compound_head(page) != head, page); | ||
894 | pages[*nr] = page; | ||
895 | (*nr)++; | ||
896 | page++; | ||
897 | refs++; | ||
898 | } while (addr += PAGE_SIZE, addr != end); | ||
899 | |||
900 | if (!page_cache_add_speculative(head, refs)) { | ||
901 | *nr -= refs; | ||
902 | return 0; | ||
903 | } | ||
904 | |||
905 | if (unlikely(pgd_val(orig) != pgd_val(*pgdp))) { | ||
906 | *nr -= refs; | ||
907 | while (refs--) | ||
908 | put_page(head); | ||
909 | return 0; | ||
910 | } | ||
911 | |||
912 | while (refs--) { | ||
913 | if (PageTail(tail)) | ||
914 | get_huge_page_tail(tail); | ||
915 | tail++; | ||
916 | } | ||
917 | |||
918 | return 1; | ||
919 | } | ||
920 | |||
878 | static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end, | 921 | static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end, |
879 | int write, struct page **pages, int *nr) | 922 | int write, struct page **pages, int *nr) |
880 | { | 923 | { |
@@ -902,6 +945,14 @@ static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end, | |||
902 | pages, nr)) | 945 | pages, nr)) |
903 | return 0; | 946 | return 0; |
904 | 947 | ||
948 | } else if (unlikely(is_hugepd(__hugepd(pmd_val(pmd))))) { | ||
949 | /* | ||
950 | * architecture have different format for hugetlbfs | ||
951 | * pmd format and THP pmd format | ||
952 | */ | ||
953 | if (!gup_huge_pd(__hugepd(pmd_val(pmd)), addr, | ||
954 | PMD_SHIFT, next, write, pages, nr)) | ||
955 | return 0; | ||
905 | } else if (!gup_pte_range(pmd, addr, next, write, pages, nr)) | 956 | } else if (!gup_pte_range(pmd, addr, next, write, pages, nr)) |
906 | return 0; | 957 | return 0; |
907 | } while (pmdp++, addr = next, addr != end); | 958 | } while (pmdp++, addr = next, addr != end); |
@@ -909,22 +960,26 @@ static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end, | |||
909 | return 1; | 960 | return 1; |
910 | } | 961 | } |
911 | 962 | ||
912 | static int gup_pud_range(pgd_t *pgdp, unsigned long addr, unsigned long end, | 963 | static int gup_pud_range(pgd_t pgd, unsigned long addr, unsigned long end, |
913 | int write, struct page **pages, int *nr) | 964 | int write, struct page **pages, int *nr) |
914 | { | 965 | { |
915 | unsigned long next; | 966 | unsigned long next; |
916 | pud_t *pudp; | 967 | pud_t *pudp; |
917 | 968 | ||
918 | pudp = pud_offset(pgdp, addr); | 969 | pudp = pud_offset(&pgd, addr); |
919 | do { | 970 | do { |
920 | pud_t pud = ACCESS_ONCE(*pudp); | 971 | pud_t pud = ACCESS_ONCE(*pudp); |
921 | 972 | ||
922 | next = pud_addr_end(addr, end); | 973 | next = pud_addr_end(addr, end); |
923 | if (pud_none(pud)) | 974 | if (pud_none(pud)) |
924 | return 0; | 975 | return 0; |
925 | if (pud_huge(pud)) { | 976 | if (unlikely(pud_huge(pud))) { |
926 | if (!gup_huge_pud(pud, pudp, addr, next, write, | 977 | if (!gup_huge_pud(pud, pudp, addr, next, write, |
927 | pages, nr)) | 978 | pages, nr)) |
979 | return 0; | ||
980 | } else if (unlikely(is_hugepd(__hugepd(pud_val(pud))))) { | ||
981 | if (!gup_huge_pd(__hugepd(pud_val(pud)), addr, | ||
982 | PUD_SHIFT, next, write, pages, nr)) | ||
928 | return 0; | 983 | return 0; |
929 | } else if (!gup_pmd_range(pud, addr, next, write, pages, nr)) | 984 | } else if (!gup_pmd_range(pud, addr, next, write, pages, nr)) |
930 | return 0; | 985 | return 0; |
@@ -970,10 +1025,20 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write, | |||
970 | local_irq_save(flags); | 1025 | local_irq_save(flags); |
971 | pgdp = pgd_offset(mm, addr); | 1026 | pgdp = pgd_offset(mm, addr); |
972 | do { | 1027 | do { |
1028 | pgd_t pgd = ACCESS_ONCE(*pgdp); | ||
1029 | |||
973 | next = pgd_addr_end(addr, end); | 1030 | next = pgd_addr_end(addr, end); |
974 | if (pgd_none(*pgdp)) | 1031 | if (pgd_none(pgd)) |
975 | break; | 1032 | break; |
976 | else if (!gup_pud_range(pgdp, addr, next, write, pages, &nr)) | 1033 | if (unlikely(pgd_huge(pgd))) { |
1034 | if (!gup_huge_pgd(pgd, pgdp, addr, next, write, | ||
1035 | pages, &nr)) | ||
1036 | break; | ||
1037 | } else if (unlikely(is_hugepd(__hugepd(pgd_val(pgd))))) { | ||
1038 | if (!gup_huge_pd(__hugepd(pgd_val(pgd)), addr, | ||
1039 | PGDIR_SHIFT, next, write, pages, &nr)) | ||
1040 | break; | ||
1041 | } else if (!gup_pud_range(pgd, addr, next, write, pages, &nr)) | ||
977 | break; | 1042 | break; |
978 | } while (pgdp++, addr = next, addr != end); | 1043 | } while (pgdp++, addr = next, addr != end); |
979 | local_irq_restore(flags); | 1044 | local_irq_restore(flags); |
diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 5b2c6875fc38..46f96c23cc27 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c | |||
@@ -804,7 +804,7 @@ int do_huge_pmd_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
804 | return VM_FAULT_OOM; | 804 | return VM_FAULT_OOM; |
805 | if (unlikely(khugepaged_enter(vma, vma->vm_flags))) | 805 | if (unlikely(khugepaged_enter(vma, vma->vm_flags))) |
806 | return VM_FAULT_OOM; | 806 | return VM_FAULT_OOM; |
807 | if (!(flags & FAULT_FLAG_WRITE) && | 807 | if (!(flags & FAULT_FLAG_WRITE) && !mm_forbids_zeropage(mm) && |
808 | transparent_hugepage_use_zero_page()) { | 808 | transparent_hugepage_use_zero_page()) { |
809 | spinlock_t *ptl; | 809 | spinlock_t *ptl; |
810 | pgtable_t pgtable; | 810 | pgtable_t pgtable; |
@@ -1399,7 +1399,8 @@ int zap_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma, | |||
1399 | * pgtable_trans_huge_withdraw after finishing pmdp related | 1399 | * pgtable_trans_huge_withdraw after finishing pmdp related |
1400 | * operations. | 1400 | * operations. |
1401 | */ | 1401 | */ |
1402 | orig_pmd = pmdp_get_and_clear(tlb->mm, addr, pmd); | 1402 | orig_pmd = pmdp_get_and_clear_full(tlb->mm, addr, pmd, |
1403 | tlb->fullmm); | ||
1403 | tlb_remove_pmd_tlb_entry(tlb, pmd, addr); | 1404 | tlb_remove_pmd_tlb_entry(tlb, pmd, addr); |
1404 | pgtable = pgtable_trans_huge_withdraw(tlb->mm, pmd); | 1405 | pgtable = pgtable_trans_huge_withdraw(tlb->mm, pmd); |
1405 | if (is_huge_zero_pmd(orig_pmd)) { | 1406 | if (is_huge_zero_pmd(orig_pmd)) { |
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 30cd96879152..919b86a2164d 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -582,7 +582,7 @@ retry_cpuset: | |||
582 | 582 | ||
583 | for_each_zone_zonelist_nodemask(zone, z, zonelist, | 583 | for_each_zone_zonelist_nodemask(zone, z, zonelist, |
584 | MAX_NR_ZONES - 1, nodemask) { | 584 | MAX_NR_ZONES - 1, nodemask) { |
585 | if (cpuset_zone_allowed_softwall(zone, htlb_alloc_mask(h))) { | 585 | if (cpuset_zone_allowed(zone, htlb_alloc_mask(h))) { |
586 | page = dequeue_huge_page_node(h, zone_to_nid(zone)); | 586 | page = dequeue_huge_page_node(h, zone_to_nid(zone)); |
587 | if (page) { | 587 | if (page) { |
588 | if (avoid_reserve) | 588 | if (avoid_reserve) |
diff --git a/mm/memory.c b/mm/memory.c index 0b3f6c71620d..4b5a282e1107 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -2627,7 +2627,7 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2627 | return VM_FAULT_SIGBUS; | 2627 | return VM_FAULT_SIGBUS; |
2628 | 2628 | ||
2629 | /* Use the zero-page for reads */ | 2629 | /* Use the zero-page for reads */ |
2630 | if (!(flags & FAULT_FLAG_WRITE)) { | 2630 | if (!(flags & FAULT_FLAG_WRITE) && !mm_forbids_zeropage(mm)) { |
2631 | entry = pte_mkspecial(pfn_pte(my_zero_pfn(address), | 2631 | entry = pte_mkspecial(pfn_pte(my_zero_pfn(address), |
2632 | vma->vm_page_prot)); | 2632 | vma->vm_page_prot)); |
2633 | page_table = pte_offset_map_lock(mm, pmd, address, &ptl); | 2633 | page_table = pte_offset_map_lock(mm, pmd, address, &ptl); |
diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 3b014d326151..864bba992735 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c | |||
@@ -233,7 +233,7 @@ static enum oom_constraint constrained_alloc(struct zonelist *zonelist, | |||
233 | /* Check this allocation failure is caused by cpuset's wall function */ | 233 | /* Check this allocation failure is caused by cpuset's wall function */ |
234 | for_each_zone_zonelist_nodemask(zone, z, zonelist, | 234 | for_each_zone_zonelist_nodemask(zone, z, zonelist, |
235 | high_zoneidx, nodemask) | 235 | high_zoneidx, nodemask) |
236 | if (!cpuset_zone_allowed_softwall(zone, gfp_mask)) | 236 | if (!cpuset_zone_allowed(zone, gfp_mask)) |
237 | cpuset_limited = true; | 237 | cpuset_limited = true; |
238 | 238 | ||
239 | if (cpuset_limited) { | 239 | if (cpuset_limited) { |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index a7198c065999..df542feaac3b 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -1990,7 +1990,7 @@ zonelist_scan: | |||
1990 | 1990 | ||
1991 | /* | 1991 | /* |
1992 | * Scan zonelist, looking for a zone with enough free. | 1992 | * Scan zonelist, looking for a zone with enough free. |
1993 | * See also __cpuset_node_allowed_softwall() comment in kernel/cpuset.c. | 1993 | * See also __cpuset_node_allowed() comment in kernel/cpuset.c. |
1994 | */ | 1994 | */ |
1995 | for_each_zone_zonelist_nodemask(zone, z, zonelist, | 1995 | for_each_zone_zonelist_nodemask(zone, z, zonelist, |
1996 | high_zoneidx, nodemask) { | 1996 | high_zoneidx, nodemask) { |
@@ -2001,7 +2001,7 @@ zonelist_scan: | |||
2001 | continue; | 2001 | continue; |
2002 | if (cpusets_enabled() && | 2002 | if (cpusets_enabled() && |
2003 | (alloc_flags & ALLOC_CPUSET) && | 2003 | (alloc_flags & ALLOC_CPUSET) && |
2004 | !cpuset_zone_allowed_softwall(zone, gfp_mask)) | 2004 | !cpuset_zone_allowed(zone, gfp_mask)) |
2005 | continue; | 2005 | continue; |
2006 | /* | 2006 | /* |
2007 | * Distribute pages in proportion to the individual | 2007 | * Distribute pages in proportion to the individual |
@@ -2529,7 +2529,7 @@ gfp_to_alloc_flags(gfp_t gfp_mask) | |||
2529 | alloc_flags |= ALLOC_HARDER; | 2529 | alloc_flags |= ALLOC_HARDER; |
2530 | /* | 2530 | /* |
2531 | * Ignore cpuset mems for GFP_ATOMIC rather than fail, see the | 2531 | * Ignore cpuset mems for GFP_ATOMIC rather than fail, see the |
2532 | * comment for __cpuset_node_allowed_softwall(). | 2532 | * comment for __cpuset_node_allowed(). |
2533 | */ | 2533 | */ |
2534 | alloc_flags &= ~ALLOC_CPUSET; | 2534 | alloc_flags &= ~ALLOC_CPUSET; |
2535 | } else if (unlikely(rt_task(current)) && !in_interrupt()) | 2535 | } else if (unlikely(rt_task(current)) && !in_interrupt()) |
diff --git a/mm/percpu.c b/mm/percpu.c index 014bab65e0ff..d39e2f4e335c 100644 --- a/mm/percpu.c +++ b/mm/percpu.c | |||
@@ -1591,7 +1591,7 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai, | |||
1591 | if (cpu == NR_CPUS) | 1591 | if (cpu == NR_CPUS) |
1592 | continue; | 1592 | continue; |
1593 | 1593 | ||
1594 | PCPU_SETUP_BUG_ON(cpu > nr_cpu_ids); | 1594 | PCPU_SETUP_BUG_ON(cpu >= nr_cpu_ids); |
1595 | PCPU_SETUP_BUG_ON(!cpu_possible(cpu)); | 1595 | PCPU_SETUP_BUG_ON(!cpu_possible(cpu)); |
1596 | PCPU_SETUP_BUG_ON(unit_map[cpu] != UINT_MAX); | 1596 | PCPU_SETUP_BUG_ON(unit_map[cpu] != UINT_MAX); |
1597 | 1597 | ||
@@ -3015,7 +3015,7 @@ retry: | |||
3015 | for_each_zone_zonelist(zone, z, zonelist, high_zoneidx) { | 3015 | for_each_zone_zonelist(zone, z, zonelist, high_zoneidx) { |
3016 | nid = zone_to_nid(zone); | 3016 | nid = zone_to_nid(zone); |
3017 | 3017 | ||
3018 | if (cpuset_zone_allowed_hardwall(zone, flags) && | 3018 | if (cpuset_zone_allowed(zone, flags | __GFP_HARDWALL) && |
3019 | get_node(cache, nid) && | 3019 | get_node(cache, nid) && |
3020 | get_node(cache, nid)->free_objects) { | 3020 | get_node(cache, nid)->free_objects) { |
3021 | obj = ____cache_alloc_node(cache, | 3021 | obj = ____cache_alloc_node(cache, |
@@ -1665,7 +1665,8 @@ static void *get_any_partial(struct kmem_cache *s, gfp_t flags, | |||
1665 | 1665 | ||
1666 | n = get_node(s, zone_to_nid(zone)); | 1666 | n = get_node(s, zone_to_nid(zone)); |
1667 | 1667 | ||
1668 | if (n && cpuset_zone_allowed_hardwall(zone, flags) && | 1668 | if (n && cpuset_zone_allowed(zone, |
1669 | flags | __GFP_HARDWALL) && | ||
1669 | n->nr_partial > s->min_partial) { | 1670 | n->nr_partial > s->min_partial) { |
1670 | object = get_partial_node(s, n, c, flags); | 1671 | object = get_partial_node(s, n, c, flags); |
1671 | if (object) { | 1672 | if (object) { |
diff --git a/mm/vmscan.c b/mm/vmscan.c index 4636d9e822c1..a384339bf718 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -2405,7 +2405,8 @@ static bool shrink_zones(struct zonelist *zonelist, struct scan_control *sc) | |||
2405 | * to global LRU. | 2405 | * to global LRU. |
2406 | */ | 2406 | */ |
2407 | if (global_reclaim(sc)) { | 2407 | if (global_reclaim(sc)) { |
2408 | if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL)) | 2408 | if (!cpuset_zone_allowed(zone, |
2409 | GFP_KERNEL | __GFP_HARDWALL)) | ||
2409 | continue; | 2410 | continue; |
2410 | 2411 | ||
2411 | lru_pages += zone_reclaimable_pages(zone); | 2412 | lru_pages += zone_reclaimable_pages(zone); |
@@ -3388,7 +3389,7 @@ void wakeup_kswapd(struct zone *zone, int order, enum zone_type classzone_idx) | |||
3388 | if (!populated_zone(zone)) | 3389 | if (!populated_zone(zone)) |
3389 | return; | 3390 | return; |
3390 | 3391 | ||
3391 | if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL)) | 3392 | if (!cpuset_zone_allowed(zone, GFP_KERNEL | __GFP_HARDWALL)) |
3392 | return; | 3393 | return; |
3393 | pgdat = zone->zone_pgdat; | 3394 | pgdat = zone->zone_pgdat; |
3394 | if (pgdat->kswapd_max_order < order) { | 3395 | if (pgdat->kswapd_max_order < order) { |
@@ -619,5 +619,5 @@ module_init(init_zbud); | |||
619 | module_exit(exit_zbud); | 619 | module_exit(exit_zbud); |
620 | 620 | ||
621 | MODULE_LICENSE("GPL"); | 621 | MODULE_LICENSE("GPL"); |
622 | MODULE_AUTHOR("Seth Jennings <sjenning@linux.vnet.ibm.com>"); | 622 | MODULE_AUTHOR("Seth Jennings <sjennings@variantweb.net>"); |
623 | MODULE_DESCRIPTION("Buddy Allocator for Compressed Pages"); | 623 | MODULE_DESCRIPTION("Buddy Allocator for Compressed Pages"); |
diff --git a/mm/zswap.c b/mm/zswap.c index ea064c1a09ba..c1543061a192 100644 --- a/mm/zswap.c +++ b/mm/zswap.c | |||
@@ -951,5 +951,5 @@ error: | |||
951 | late_initcall(init_zswap); | 951 | late_initcall(init_zswap); |
952 | 952 | ||
953 | MODULE_LICENSE("GPL"); | 953 | MODULE_LICENSE("GPL"); |
954 | MODULE_AUTHOR("Seth Jennings <sjenning@linux.vnet.ibm.com>"); | 954 | MODULE_AUTHOR("Seth Jennings <sjennings@variantweb.net>"); |
955 | MODULE_DESCRIPTION("Compressed cache for swap pages"); | 955 | MODULE_DESCRIPTION("Compressed cache for swap pages"); |