aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorKirill A. Shutemov <kirill.shutemov@linux.intel.com>2014-06-04 19:10:54 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-04 19:54:12 -0400
commita9b0f8618d46ba027243b8ecb5c2468a7112d235 (patch)
tree31ccf1d5066a3b7a3b163326ec6a9e462ffe0ed6 /mm
parent7d018176e6d50510b142bccbd60d8c6ed5e72e56 (diff)
mm: nominate faultaround area in bytes rather than page order
There is evidencs that the faultaround feature is less relevant on architectures with page size bigger then 4k. Which makes sense since page fault overhead per byte of mapped area should be less there. Let's rework the feature to specify faultaround area in bytes instead of page order. It's 64 kilobytes for now. The patch effectively disables faultaround on architectures with page size >= 64k (like ppc64). It's possible that some other size of faultaround area is relevant for a platform. We can expose `fault_around_bytes' variable to arch-specific code once such platforms will be found. Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Cc: Rusty Russell <rusty@rustcorp.com.au> Cc: Hugh Dickins <hughd@google.com> Cc: Madhavan Srinivasan <maddy@linux.vnet.ibm.com> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Rik van Riel <riel@redhat.com> Cc: Mel Gorman <mgorman@suse.de> Cc: Andi Kleen <ak@linux.intel.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Ingo Molnar <mingo@kernel.org> Cc: Dave Hansen <dave.hansen@intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/memory.c62
1 files changed, 23 insertions, 39 deletions
diff --git a/mm/memory.c b/mm/memory.c
index e7ccbac25b72..62a08a7badc4 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2758,63 +2758,47 @@ void do_set_pte(struct vm_area_struct *vma, unsigned long address,
2758 update_mmu_cache(vma, address, pte); 2758 update_mmu_cache(vma, address, pte);
2759} 2759}
2760 2760
2761#define FAULT_AROUND_ORDER 4 2761static unsigned long fault_around_bytes = 65536;
2762
2763static inline unsigned long fault_around_pages(void)
2764{
2765 return rounddown_pow_of_two(fault_around_bytes) / PAGE_SIZE;
2766}
2767
2768static inline unsigned long fault_around_mask(void)
2769{
2770 return ~(rounddown_pow_of_two(fault_around_bytes) - 1) & PAGE_MASK;
2771}
2762 2772
2763#ifdef CONFIG_DEBUG_FS
2764static unsigned int fault_around_order = FAULT_AROUND_ORDER;
2765 2773
2766static int fault_around_order_get(void *data, u64 *val) 2774#ifdef CONFIG_DEBUG_FS
2775static int fault_around_bytes_get(void *data, u64 *val)
2767{ 2776{
2768 *val = fault_around_order; 2777 *val = fault_around_bytes;
2769 return 0; 2778 return 0;
2770} 2779}
2771 2780
2772static int fault_around_order_set(void *data, u64 val) 2781static int fault_around_bytes_set(void *data, u64 val)
2773{ 2782{
2774 BUILD_BUG_ON((1UL << FAULT_AROUND_ORDER) > PTRS_PER_PTE); 2783 if (val / PAGE_SIZE > PTRS_PER_PTE)
2775 if (1UL << val > PTRS_PER_PTE)
2776 return -EINVAL; 2784 return -EINVAL;
2777 fault_around_order = val; 2785 fault_around_bytes = val;
2778 return 0; 2786 return 0;
2779} 2787}
2780DEFINE_SIMPLE_ATTRIBUTE(fault_around_order_fops, 2788DEFINE_SIMPLE_ATTRIBUTE(fault_around_bytes_fops,
2781 fault_around_order_get, fault_around_order_set, "%llu\n"); 2789 fault_around_bytes_get, fault_around_bytes_set, "%llu\n");
2782 2790
2783static int __init fault_around_debugfs(void) 2791static int __init fault_around_debugfs(void)
2784{ 2792{
2785 void *ret; 2793 void *ret;
2786 2794
2787 ret = debugfs_create_file("fault_around_order", 0644, NULL, NULL, 2795 ret = debugfs_create_file("fault_around_bytes", 0644, NULL, NULL,
2788 &fault_around_order_fops); 2796 &fault_around_bytes_fops);
2789 if (!ret) 2797 if (!ret)
2790 pr_warn("Failed to create fault_around_order in debugfs"); 2798 pr_warn("Failed to create fault_around_bytes in debugfs");
2791 return 0; 2799 return 0;
2792} 2800}
2793late_initcall(fault_around_debugfs); 2801late_initcall(fault_around_debugfs);
2794
2795static inline unsigned long fault_around_pages(void)
2796{
2797 return 1UL << fault_around_order;
2798}
2799
2800static inline unsigned long fault_around_mask(void)
2801{
2802 return ~((1UL << (PAGE_SHIFT + fault_around_order)) - 1);
2803}
2804#else
2805static inline unsigned long fault_around_pages(void)
2806{
2807 unsigned long nr_pages;
2808
2809 nr_pages = 1UL << FAULT_AROUND_ORDER;
2810 BUILD_BUG_ON(nr_pages > PTRS_PER_PTE);
2811 return nr_pages;
2812}
2813
2814static inline unsigned long fault_around_mask(void)
2815{
2816 return ~((1UL << (PAGE_SHIFT + FAULT_AROUND_ORDER)) - 1);
2817}
2818#endif 2802#endif
2819 2803
2820static void do_fault_around(struct vm_area_struct *vma, unsigned long address, 2804static void do_fault_around(struct vm_area_struct *vma, unsigned long address,
@@ -2871,7 +2855,7 @@ static int do_read_fault(struct mm_struct *mm, struct vm_area_struct *vma,
2871 * if page by the offset is not ready to be mapped (cold cache or 2855 * if page by the offset is not ready to be mapped (cold cache or
2872 * something). 2856 * something).
2873 */ 2857 */
2874 if (vma->vm_ops->map_pages) { 2858 if (vma->vm_ops->map_pages && fault_around_pages() > 1) {
2875 pte = pte_offset_map_lock(mm, pmd, address, &ptl); 2859 pte = pte_offset_map_lock(mm, pmd, address, &ptl);
2876 do_fault_around(vma, address, pte, pgoff, flags); 2860 do_fault_around(vma, address, pte, pgoff, flags);
2877 if (!pte_same(*pte, orig_pte)) 2861 if (!pte_same(*pte, orig_pte))