diff options
author | Steven Rostedt <srostedt@redhat.com> | 2013-01-23 19:14:03 -0500 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2013-01-23 19:14:03 -0500 |
commit | 8e306f694496f6191ca3a2cde469d20333865fc8 (patch) | |
tree | 1a25e7cdda38fa31a3fddedd6b315b0323634e37 /mm | |
parent | 13fa57aab5fd50aa084671be2874a3ce49a6a9a7 (diff) | |
parent | 0829a6cc39cfcd76caaf562b4254c95392463b62 (diff) |
Merge tag 'v3.0.59' into v3.0-rt
This is the 3.0.59 stable release
Diffstat (limited to 'mm')
-rw-r--r-- | mm/compaction.c | 6 | ||||
-rw-r--r-- | mm/huge_memory.c | 3 | ||||
-rw-r--r-- | mm/memory.c | 18 | ||||
-rw-r--r-- | mm/page_alloc.c | 2 |
4 files changed, 21 insertions, 8 deletions
diff --git a/mm/compaction.c b/mm/compaction.c index 8ea7308601bc..b4689f8117ba 100644 --- a/mm/compaction.c +++ b/mm/compaction.c @@ -714,14 +714,12 @@ static int compact_node(int nid) } /* Compact all nodes in the system */ -static int compact_nodes(void) +static void compact_nodes(void) { int nid; for_each_online_node(nid) compact_node(nid); - - return COMPACT_COMPLETE; } /* The written value is actually unused, all memory is compacted */ @@ -732,7 +730,7 @@ int sysctl_compaction_handler(struct ctl_table *table, int write, void __user *buffer, size_t *length, loff_t *ppos) { if (write) - return compact_nodes(); + compact_nodes(); return 0; } diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 8cc11dda6a74..a9ab45ec7d5e 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -920,6 +920,8 @@ int do_huge_pmd_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, count_vm_event(THP_FAULT_FALLBACK); ret = do_huge_pmd_wp_page_fallback(mm, vma, address, pmd, orig_pmd, page, haddr); + if (ret & VM_FAULT_OOM) + split_huge_page(page); put_page(page); goto out; } @@ -927,6 +929,7 @@ int do_huge_pmd_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, if (unlikely(mem_cgroup_newpage_charge(new_page, mm, GFP_KERNEL))) { put_page(new_page); + split_huge_page(page); put_page(page); ret |= VM_FAULT_OOM; goto out; diff --git a/mm/memory.c b/mm/memory.c index 8b098bb232f8..de978764882d 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -3489,6 +3489,7 @@ int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma, if (unlikely(is_vm_hugetlb_page(vma))) return hugetlb_fault(mm, vma, address, flags); +retry: pgd = pgd_offset(mm, address); pud = pud_alloc(mm, pgd, address); if (!pud) @@ -3502,13 +3503,24 @@ int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma, pmd, flags); } else { pmd_t orig_pmd = *pmd; + int ret; + barrier(); if (pmd_trans_huge(orig_pmd)) { if (flags & FAULT_FLAG_WRITE && !pmd_write(orig_pmd) && - !pmd_trans_splitting(orig_pmd)) - return do_huge_pmd_wp_page(mm, vma, address, - pmd, orig_pmd); + !pmd_trans_splitting(orig_pmd)) { + ret = do_huge_pmd_wp_page(mm, vma, address, pmd, + orig_pmd); + /* + * If COW results in an oom, the huge pmd will + * have been split, so retry the fault on the + * pte for a smaller charge. + */ + if (unlikely(ret & VM_FAULT_OOM)) + goto retry; + return ret; + } return 0; } } diff --git a/mm/page_alloc.c b/mm/page_alloc.c index c645e07cbfee..9534b6ccc0fc 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -5554,7 +5554,7 @@ static inline int pfn_to_bitidx(struct zone *zone, unsigned long pfn) pfn &= (PAGES_PER_SECTION-1); return (pfn >> pageblock_order) * NR_PAGEBLOCK_BITS; #else - pfn = pfn - zone->zone_start_pfn; + pfn = pfn - round_down(zone->zone_start_pfn, pageblock_nr_pages); return (pfn >> pageblock_order) * NR_PAGEBLOCK_BITS; #endif /* CONFIG_SPARSEMEM */ } |