mm: drop support of non-linear mapping from fault codepath
[deliverable/linux.git] / include / linux / mm.h
index dd5ea3016fc4e854ded6b1e7c2e096224d83317f..376e5c325dee02821afd97eeb7442c6c5d362143 100644 (file)
@@ -206,21 +206,19 @@ extern unsigned int kobjsize(const void *objp);
 extern pgprot_t protection_map[16];
 
 #define FAULT_FLAG_WRITE       0x01    /* Fault was a write access */
-#define FAULT_FLAG_NONLINEAR   0x02    /* Fault was via a nonlinear mapping */
-#define FAULT_FLAG_MKWRITE     0x04    /* Fault was mkwrite of existing pte */
-#define FAULT_FLAG_ALLOW_RETRY 0x08    /* Retry fault if blocking */
-#define FAULT_FLAG_RETRY_NOWAIT        0x10    /* Don't drop mmap_sem and wait when retrying */
-#define FAULT_FLAG_KILLABLE    0x20    /* The fault task is in SIGKILL killable region */
-#define FAULT_FLAG_TRIED       0x40    /* second try */
-#define FAULT_FLAG_USER                0x80    /* The fault originated in userspace */
+#define FAULT_FLAG_MKWRITE     0x02    /* Fault was mkwrite of existing pte */
+#define FAULT_FLAG_ALLOW_RETRY 0x04    /* Retry fault if blocking */
+#define FAULT_FLAG_RETRY_NOWAIT        0x08    /* Don't drop mmap_sem and wait when retrying */
+#define FAULT_FLAG_KILLABLE    0x10    /* The fault task is in SIGKILL killable region */
+#define FAULT_FLAG_TRIED       0x20    /* Second try */
+#define FAULT_FLAG_USER                0x40    /* The fault originated in userspace */
 
 /*
  * 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
  * of VM_FAULT_xxx flags that give details about how the fault was handled.
  *
- * pgoff should be used in favour of virtual_address, if possible. If pgoff
- * is used, one may implement ->remap_pages to get nonlinear mapping support.
+ * pgoff should be used in favour of virtual_address, if possible.
  */
 struct vm_fault {
        unsigned int flags;             /* FAULT_FLAG_xxx flags */
@@ -446,6 +444,12 @@ static inline struct page *compound_head_by_tail(struct page *tail)
        return tail;
 }
 
+/*
+ * Since either compound page could be dismantled asynchronously in THP
+ * or we access asynchronously arbitrary positioned struct page, there
+ * would be tail flag race. To handle this race, we should call
+ * smp_rmb() before checking tail flag. compound_head_by_tail() did it.
+ */
 static inline struct page *compound_head(struct page *page)
 {
        if (unlikely(PageTail(page)))
@@ -453,6 +457,18 @@ static inline struct page *compound_head(struct page *page)
        return page;
 }
 
+/*
+ * If we access compound page synchronously such as access to
+ * allocated page, there is no need to handle tail flag race, so we can
+ * check tail flag directly without any synchronization primitive.
+ */
+static inline struct page *compound_head_fast(struct page *page)
+{
+       if (unlikely(PageTail(page)))
+               return page->first_page;
+       return page;
+}
+
 /*
  * The atomic page->_mapcount, starts from -1: so that transitions
  * both from it and to it can be tracked, using atomic_inc_and_test
@@ -531,7 +547,14 @@ static inline void get_page(struct page *page)
 static inline struct page *virt_to_head_page(const void *x)
 {
        struct page *page = virt_to_page(x);
-       return compound_head(page);
+
+       /*
+        * We don't need to worry about synchronization of tail flag
+        * when we call virt_to_head_page() since it is only called for
+        * already allocated page and this page won't be freed until
+        * this virt_to_head_page() is finished. So use _fast variant.
+        */
+       return compound_head_fast(page);
 }
 
 /*
@@ -1121,7 +1144,6 @@ extern void user_shm_unlock(size_t, struct user_struct *);
  * Parameter block passed down to zap_pte_range in exceptional cases.
  */
 struct zap_details {
-       struct vm_area_struct *nonlinear_vma;   /* Check page->index if set */
        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 */
This page took 0.029255 seconds and 5 git commands to generate.