aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
Diffstat (limited to 'mm')
-rw-r--r--mm/gup.c81
-rw-r--r--mm/huge_memory.c5
-rw-r--r--mm/hugetlb.c2
-rw-r--r--mm/memory.c2
-rw-r--r--mm/oom_kill.c2
-rw-r--r--mm/page_alloc.c6
-rw-r--r--mm/percpu.c2
-rw-r--r--mm/slab.c2
-rw-r--r--mm/slub.c3
-rw-r--r--mm/vmscan.c5
-rw-r--r--mm/zbud.c2
-rw-r--r--mm/zswap.c2
12 files changed, 91 insertions, 23 deletions
diff --git a/mm/gup.c b/mm/gup.c
index cd62c8c90d4a..0ca1df9075ab 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -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
878static 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
878static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end, 921static 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
912static int gup_pud_range(pgd_t *pgdp, unsigned long addr, unsigned long end, 963static 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
diff --git a/mm/slab.c b/mm/slab.c
index 79e15f0a2a6e..fee275b5b6b7 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -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,
diff --git a/mm/slub.c b/mm/slub.c
index 386bbed76e94..765c5884d03d 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -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) {
diff --git a/mm/zbud.c b/mm/zbud.c
index ecf1dbef6983..ec71b37fb06c 100644
--- a/mm/zbud.c
+++ b/mm/zbud.c
@@ -619,5 +619,5 @@ module_init(init_zbud);
619module_exit(exit_zbud); 619module_exit(exit_zbud);
620 620
621MODULE_LICENSE("GPL"); 621MODULE_LICENSE("GPL");
622MODULE_AUTHOR("Seth Jennings <sjenning@linux.vnet.ibm.com>"); 622MODULE_AUTHOR("Seth Jennings <sjennings@variantweb.net>");
623MODULE_DESCRIPTION("Buddy Allocator for Compressed Pages"); 623MODULE_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:
951late_initcall(init_zswap); 951late_initcall(init_zswap);
952 952
953MODULE_LICENSE("GPL"); 953MODULE_LICENSE("GPL");
954MODULE_AUTHOR("Seth Jennings <sjenning@linux.vnet.ibm.com>"); 954MODULE_AUTHOR("Seth Jennings <sjennings@variantweb.net>");
955MODULE_DESCRIPTION("Compressed cache for swap pages"); 955MODULE_DESCRIPTION("Compressed cache for swap pages");