]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - include/linux/mm.h
mm: replace FAULT_FLAG_SIZE with parameter to huge_fault
[karo-tx-linux.git] / include / linux / mm.h
index b84615b0f64c294eebb72095cc8dbc874b4ae22b..c65aa43b5712a30a79261fbb1c9a884ff56d9aef 100644 (file)
@@ -76,6 +76,10 @@ extern int mmap_rnd_compat_bits __read_mostly;
 #define page_to_virt(x)        __va(PFN_PHYS(page_to_pfn(x)))
 #endif
 
+#ifndef lm_alias
+#define lm_alias(x)    __va(__pa_symbol(x))
+#endif
+
 /*
  * To prevent common memory management code establishing
  * a zero page mapping on a read fault.
@@ -281,6 +285,17 @@ extern pgprot_t protection_map[16];
 #define FAULT_FLAG_REMOTE      0x80    /* faulting for non current tsk/mm */
 #define FAULT_FLAG_INSTRUCTION  0x100  /* The fault was during an instruction fetch */
 
+#define FAULT_FLAG_TRACE \
+       { FAULT_FLAG_WRITE,             "WRITE" }, \
+       { FAULT_FLAG_MKWRITE,           "MKWRITE" }, \
+       { FAULT_FLAG_ALLOW_RETRY,       "ALLOW_RETRY" }, \
+       { FAULT_FLAG_RETRY_NOWAIT,      "RETRY_NOWAIT" }, \
+       { FAULT_FLAG_KILLABLE,          "KILLABLE" }, \
+       { FAULT_FLAG_TRIED,             "TRIED" }, \
+       { FAULT_FLAG_USER,              "USER" }, \
+       { FAULT_FLAG_REMOTE,            "REMOTE" }, \
+       { FAULT_FLAG_INSTRUCTION,       "INSTRUCTION" }
+
 /*
  * vm_fault is filled by the the pagefault handler and passed to the vma's
  * ->fault function. The vma's ->fault is responsible for returning a bitmask
@@ -299,6 +314,9 @@ struct vm_fault {
        unsigned long address;          /* Faulting virtual address */
        pmd_t *pmd;                     /* Pointer to pmd entry matching
                                         * the 'address' */
+       pud_t *pud;                     /* Pointer to pud entry matching
+                                        * the 'address'
+                                        */
        pte_t orig_pte;                 /* Value of PTE at the time of fault */
 
        struct page *cow_page;          /* Page handler may use for COW fault */
@@ -326,6 +344,13 @@ struct vm_fault {
                                         */
 };
 
+/* page entry size for vm->huge_fault() */
+enum page_entry_size {
+       PE_SIZE_PTE = 0,
+       PE_SIZE_PMD,
+       PE_SIZE_PUD,
+};
+
 /*
  * These are the virtual MM functions - opening of an area, closing and
  * unmapping it (needed to keep files on disk up-to-date etc), pointer
@@ -335,18 +360,17 @@ struct vm_operations_struct {
        void (*open)(struct vm_area_struct * area);
        void (*close)(struct vm_area_struct * area);
        int (*mremap)(struct vm_area_struct * area);
-       int (*fault)(struct vm_area_struct *vma, struct vm_fault *vmf);
-       int (*pmd_fault)(struct vm_area_struct *, unsigned long address,
-                                               pmd_t *, unsigned int flags);
+       int (*fault)(struct vm_fault *vmf);
+       int (*huge_fault)(struct vm_fault *vmf, enum page_entry_size pe_size);
        void (*map_pages)(struct vm_fault *vmf,
                        pgoff_t start_pgoff, pgoff_t end_pgoff);
 
        /* notification that a previously read-only page is about to become
         * writable, if an error is returned it will cause a SIGBUS */
-       int (*page_mkwrite)(struct vm_area_struct *vma, struct vm_fault *vmf);
+       int (*page_mkwrite)(struct vm_fault *vmf);
 
        /* same as page_mkwrite when using VM_PFNMAP|VM_MIXEDMAP */
-       int (*pfn_mkwrite)(struct vm_area_struct *vma, struct vm_fault *vmf);
+       int (*pfn_mkwrite)(struct vm_fault *vmf);
 
        /* called by access_process_vm when get_user_pages() fails, typically
         * for use by special VMAs that can switch between memory and hardware
@@ -402,6 +426,10 @@ static inline int pmd_devmap(pmd_t pmd)
 {
        return 0;
 }
+static inline int pud_devmap(pud_t pud)
+{
+       return 0;
+}
 #endif
 
 /*
@@ -1107,6 +1135,20 @@ static inline void clear_page_pfmemalloc(struct page *page)
                         VM_FAULT_HWPOISON | VM_FAULT_HWPOISON_LARGE | \
                         VM_FAULT_FALLBACK)
 
+#define VM_FAULT_RESULT_TRACE \
+       { VM_FAULT_OOM,                 "OOM" }, \
+       { VM_FAULT_SIGBUS,              "SIGBUS" }, \
+       { VM_FAULT_MAJOR,               "MAJOR" }, \
+       { VM_FAULT_WRITE,               "WRITE" }, \
+       { VM_FAULT_HWPOISON,            "HWPOISON" }, \
+       { VM_FAULT_HWPOISON_LARGE,      "HWPOISON_LARGE" }, \
+       { VM_FAULT_SIGSEGV,             "SIGSEGV" }, \
+       { VM_FAULT_NOPAGE,              "NOPAGE" }, \
+       { VM_FAULT_LOCKED,              "LOCKED" }, \
+       { VM_FAULT_RETRY,               "RETRY" }, \
+       { VM_FAULT_FALLBACK,            "FALLBACK" }, \
+       { VM_FAULT_DONE_COW,            "DONE_COW" }
+
 /* Encode hstate index for a hwpoisoned large page */
 #define VM_FAULT_SET_HINDEX(x) ((x) << 12)
 #define VM_FAULT_GET_HINDEX(x) (((x) >> 12) & 0xf)
@@ -1124,8 +1166,7 @@ extern void pagefault_out_of_memory(void);
  */
 #define SHOW_MEM_FILTER_NODES          (0x0001u)       /* disallowed nodes */
 
-extern void show_free_areas(unsigned int flags);
-extern bool skip_free_areas_node(unsigned int flags, int nid);
+extern void show_free_areas(unsigned int flags, nodemask_t *nodemask);
 
 int shmem_zero_setup(struct vm_area_struct *);
 #ifdef CONFIG_SHMEM
@@ -1148,8 +1189,6 @@ struct zap_details {
        struct address_space *check_mapping;    /* Check page->mapping if set */
        pgoff_t first_index;                    /* Lowest page->index to unmap */
        pgoff_t last_index;                     /* Highest page->index to unmap */
-       bool ignore_dirty;                      /* Ignore dirty pages */
-       bool check_swap_entries;                /* Check also swap entries */
 };
 
 struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr,
@@ -1160,12 +1199,16 @@ struct page *vm_normal_page_pmd(struct vm_area_struct *vma, unsigned long addr,
 int zap_vma_ptes(struct vm_area_struct *vma, unsigned long address,
                unsigned long size);
 void zap_page_range(struct vm_area_struct *vma, unsigned long address,
-               unsigned long size, struct zap_details *);
+               unsigned long size);
 void unmap_vmas(struct mmu_gather *tlb, struct vm_area_struct *start_vma,
                unsigned long start, unsigned long end);
 
 /**
  * mm_walk - callbacks for walk_page_range
+ * @pud_entry: if set, called for each non-empty PUD (2nd-level) entry
+ *            this handler should only handle pud_trans_huge() puds.
+ *            the pmd_entry or pte_entry callbacks will be used for
+ *            regular PUDs.
  * @pmd_entry: if set, called for each non-empty PMD (3rd-level) entry
  *            this handler is required to be able to handle
  *            pmd_trans_huge() pmds.  They may simply choose to
@@ -1185,6 +1228,8 @@ void unmap_vmas(struct mmu_gather *tlb, struct vm_area_struct *start_vma,
  * (see the comment on walk_page_range() for more details)
  */
 struct mm_walk {
+       int (*pud_entry)(pud_t *pud, unsigned long addr,
+                        unsigned long next, struct mm_walk *walk);
        int (*pmd_entry)(pmd_t *pmd, unsigned long addr,
                         unsigned long next, struct mm_walk *walk);
        int (*pte_entry)(pte_t *pte, unsigned long addr,
@@ -1355,6 +1400,16 @@ static inline bool vma_is_anonymous(struct vm_area_struct *vma)
        return !vma->vm_ops;
 }
 
+#ifdef CONFIG_SHMEM
+/*
+ * The vma_is_shmem is not inline because it is used only by slow
+ * paths in userfault.
+ */
+bool vma_is_shmem(struct vm_area_struct *vma);
+#else
+static inline bool vma_is_shmem(struct vm_area_struct *vma) { return false; }
+#endif
+
 static inline int stack_guard_page_start(struct vm_area_struct *vma,
                                             unsigned long addr)
 {
@@ -1758,8 +1813,26 @@ static inline spinlock_t *pmd_lock(struct mm_struct *mm, pmd_t *pmd)
        return ptl;
 }
 
-extern void __init pagecache_init(void);
+/*
+ * No scalability reason to split PUD locks yet, but follow the same pattern
+ * as the PMD locks to make it easier if we decide to.  The VM should not be
+ * considered ready to switch to split PUD locks yet; there may be places
+ * which need to be converted from page_table_lock.
+ */
+static inline spinlock_t *pud_lockptr(struct mm_struct *mm, pud_t *pud)
+{
+       return &mm->page_table_lock;
+}
 
+static inline spinlock_t *pud_lock(struct mm_struct *mm, pud_t *pud)
+{
+       spinlock_t *ptl = pud_lockptr(mm, pud);
+
+       spin_lock(ptl);
+       return ptl;
+}
+
+extern void __init pagecache_init(void);
 extern void free_area_init(unsigned long * zones_size);
 extern void free_area_init_node(int nid, unsigned long * zones_size,
                unsigned long zone_start_pfn, unsigned long *zholes_size);
@@ -1896,7 +1969,7 @@ extern void setup_per_zone_wmarks(void);
 extern int __meminit init_per_zone_wmark_min(void);
 extern void mem_init(void);
 extern void __init mmap_init(void);
-extern void show_mem(unsigned int flags);
+extern void show_mem(unsigned int flags, nodemask_t *nodemask);
 extern long si_mem_available(void);
 extern void si_meminfo(struct sysinfo * val);
 extern void si_meminfo_node(struct sysinfo *val, int nid);
@@ -1904,8 +1977,8 @@ extern void si_meminfo_node(struct sysinfo *val, int nid);
 extern unsigned long arch_reserved_kernel_pages(void);
 #endif
 
-extern __printf(2, 3)
-void warn_alloc(gfp_t gfp_mask, const char *fmt, ...);
+extern __printf(3, 4)
+void warn_alloc(gfp_t gfp_mask, nodemask_t *nodemask, const char *fmt, ...);
 
 extern void setup_per_cpu_pageset(void);
 
@@ -2045,6 +2118,7 @@ static inline void mm_populate(unsigned long addr, unsigned long len) {}
 
 /* These take the mm semaphore themselves */
 extern int __must_check vm_brk(unsigned long, unsigned long);
+extern int __must_check vm_brk_flags(unsigned long, unsigned long, unsigned long);
 extern int vm_munmap(unsigned long, size_t);
 extern unsigned long __must_check vm_mmap(struct file *, unsigned long,
         unsigned long, unsigned long,
@@ -2088,10 +2162,10 @@ extern void truncate_inode_pages_range(struct address_space *,
 extern void truncate_inode_pages_final(struct address_space *);
 
 /* generic vm_area_ops exported for stackable file systems */
-extern int filemap_fault(struct vm_area_struct *, struct vm_fault *);
+extern int filemap_fault(struct vm_fault *vmf);
 extern void filemap_map_pages(struct vm_fault *vmf,
                pgoff_t start_pgoff, pgoff_t end_pgoff);
-extern int filemap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf);
+extern int filemap_page_mkwrite(struct vm_fault *vmf);
 
 /* mm/page-writeback.c */
 int write_one_page(struct page *page, int wait);
@@ -2396,6 +2470,10 @@ extern void clear_huge_page(struct page *page,
 extern void copy_user_huge_page(struct page *dst, struct page *src,
                                unsigned long addr, struct vm_area_struct *vma,
                                unsigned int pages_per_huge_page);
+extern long copy_huge_page_from_user(struct page *dst_page,
+                               const void __user *usr_src,
+                               unsigned int pages_per_huge_page,
+                               bool allow_pagefault);
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLBFS */
 
 extern struct page_ext_operations debug_guardpage_ops;