Merge tag 'mtd/for-6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux
[linux-2.6-microblaze.git] / include / linux / mm_types.h
index 7d30dc4..36c5b43 100644 (file)
@@ -141,20 +141,6 @@ struct page {
                struct {        /* Tail pages of compound page */
                        unsigned long compound_head;    /* Bit zero is set */
                };
-               struct {        /* Page table pages */
-                       unsigned long _pt_pad_1;        /* compound_head */
-                       pgtable_t pmd_huge_pte; /* protected by page->ptl */
-                       unsigned long _pt_pad_2;        /* mapping */
-                       union {
-                               struct mm_struct *pt_mm; /* x86 pgds only */
-                               atomic_t pt_frag_refcount; /* powerpc */
-                       };
-#if ALLOC_SPLIT_PTLOCKS
-                       spinlock_t *ptl;
-#else
-                       spinlock_t ptl;
-#endif
-               };
                struct {        /* ZONE_DEVICE pages */
                        /** @pgmap: Points to the hosting device page map. */
                        struct dev_pagemap *pgmap;
@@ -262,6 +248,14 @@ static inline struct page *encoded_page_ptr(struct encoded_page *page)
        return (struct page *)(~ENCODE_PAGE_BITS & (unsigned long)page);
 }
 
+/*
+ * A swap entry has to fit into a "unsigned long", as the entry is hidden
+ * in the "index" field of the swapper address space.
+ */
+typedef struct {
+       unsigned long val;
+} swp_entry_t;
+
 /**
  * struct folio - Represents a contiguous set of bytes.
  * @flags: Identical to the page flags.
@@ -272,14 +266,12 @@ static inline struct page *encoded_page_ptr(struct encoded_page *page)
  * @index: Offset within the file, in units of pages.  For anonymous memory,
  *    this is the index from the beginning of the mmap.
  * @private: Filesystem per-folio data (see folio_attach_private()).
- *    Used for swp_entry_t if folio_test_swapcache().
+ * @swap: Used for swp_entry_t if folio_test_swapcache().
  * @_mapcount: Do not access this member directly.  Use folio_mapcount() to
  *    find out how many times this folio is mapped by userspace.
  * @_refcount: Do not access this member directly.  Use folio_ref_count()
  *    to find how many references there are to this folio.
  * @memcg_data: Memory Control Group data.
- * @_folio_dtor: Which destructor to use for this folio.
- * @_folio_order: Do not use directly, call folio_order().
  * @_entire_mapcount: Do not use directly, call folio_entire_mapcount().
  * @_nr_pages_mapped: Do not use directly, call folio_mapcount().
  * @_pincount: Do not use directly, call folio_maybe_dma_pinned().
@@ -317,7 +309,10 @@ struct folio {
                        };
                        struct address_space *mapping;
                        pgoff_t index;
-                       void *private;
+                       union {
+                               void *private;
+                               swp_entry_t swap;
+                       };
                        atomic_t _mapcount;
                        atomic_t _refcount;
 #ifdef CONFIG_MEMCG
@@ -331,9 +326,8 @@ struct folio {
                struct {
                        unsigned long _flags_1;
                        unsigned long _head_1;
+                       unsigned long _folio_avail;
        /* public: */
-                       unsigned char _folio_dtor;
-                       unsigned char _folio_order;
                        atomic_t _entire_mapcount;
                        atomic_t _nr_pages_mapped;
                        atomic_t _pincount;
@@ -391,8 +385,89 @@ FOLIO_MATCH(compound_head, _head_1);
                        offsetof(struct page, pg) + 2 * sizeof(struct page))
 FOLIO_MATCH(flags, _flags_2);
 FOLIO_MATCH(compound_head, _head_2);
+FOLIO_MATCH(flags, _flags_2a);
+FOLIO_MATCH(compound_head, _head_2a);
 #undef FOLIO_MATCH
 
+/**
+ * struct ptdesc -    Memory descriptor for page tables.
+ * @__page_flags:     Same as page flags. Unused for page tables.
+ * @pt_rcu_head:      For freeing page table pages.
+ * @pt_list:          List of used page tables. Used for s390 and x86.
+ * @_pt_pad_1:        Padding that aliases with page's compound head.
+ * @pmd_huge_pte:     Protected by ptdesc->ptl, used for THPs.
+ * @__page_mapping:   Aliases with page->mapping. Unused for page tables.
+ * @pt_mm:            Used for x86 pgds.
+ * @pt_frag_refcount: For fragmented page table tracking. Powerpc and s390 only.
+ * @_pt_pad_2:        Padding to ensure proper alignment.
+ * @ptl:              Lock for the page table.
+ * @__page_type:      Same as page->page_type. Unused for page tables.
+ * @_refcount:        Same as page refcount. Used for s390 page tables.
+ * @pt_memcg_data:    Memcg data. Tracked for page tables here.
+ *
+ * This struct overlays struct page for now. Do not modify without a good
+ * understanding of the issues.
+ */
+struct ptdesc {
+       unsigned long __page_flags;
+
+       union {
+               struct rcu_head pt_rcu_head;
+               struct list_head pt_list;
+               struct {
+                       unsigned long _pt_pad_1;
+                       pgtable_t pmd_huge_pte;
+               };
+       };
+       unsigned long __page_mapping;
+
+       union {
+               struct mm_struct *pt_mm;
+               atomic_t pt_frag_refcount;
+       };
+
+       union {
+               unsigned long _pt_pad_2;
+#if ALLOC_SPLIT_PTLOCKS
+               spinlock_t *ptl;
+#else
+               spinlock_t ptl;
+#endif
+       };
+       unsigned int __page_type;
+       atomic_t _refcount;
+#ifdef CONFIG_MEMCG
+       unsigned long pt_memcg_data;
+#endif
+};
+
+#define TABLE_MATCH(pg, pt)                                            \
+       static_assert(offsetof(struct page, pg) == offsetof(struct ptdesc, pt))
+TABLE_MATCH(flags, __page_flags);
+TABLE_MATCH(compound_head, pt_list);
+TABLE_MATCH(compound_head, _pt_pad_1);
+TABLE_MATCH(mapping, __page_mapping);
+TABLE_MATCH(rcu_head, pt_rcu_head);
+TABLE_MATCH(page_type, __page_type);
+TABLE_MATCH(_refcount, _refcount);
+#ifdef CONFIG_MEMCG
+TABLE_MATCH(memcg_data, pt_memcg_data);
+#endif
+#undef TABLE_MATCH
+static_assert(sizeof(struct ptdesc) <= sizeof(struct page));
+
+#define ptdesc_page(pt)                        (_Generic((pt),                 \
+       const struct ptdesc *:          (const struct page *)(pt),      \
+       struct ptdesc *:                (struct page *)(pt)))
+
+#define ptdesc_folio(pt)               (_Generic((pt),                 \
+       const struct ptdesc *:          (const struct folio *)(pt),     \
+       struct ptdesc *:                (struct folio *)(pt)))
+
+#define page_ptdesc(p)                 (_Generic((p),                  \
+       const struct page *:            (const struct ptdesc *)(p),     \
+       struct page *:                  (struct ptdesc *)(p)))
+
 /*
  * Used for sizing the vmemmap region on some architectures
  */
@@ -812,7 +887,7 @@ struct mm_struct {
 #ifdef CONFIG_KSM
                /*
                 * Represent how many pages of this process are involved in KSM
-                * merging.
+                * merging (not including ksm_zero_pages).
                 */
                unsigned long ksm_merging_pages;
                /*
@@ -820,7 +895,12 @@ struct mm_struct {
                 * including merged and not merged.
                 */
                unsigned long ksm_rmap_items;
-#endif
+               /*
+                * Represent how many empty pages are merged with kernel zero
+                * pages when enabling KSM use_zero_pages.
+                */
+               unsigned long ksm_zero_pages;
+#endif /* CONFIG_KSM */
 #ifdef CONFIG_LRU_GEN
                struct {
                        /* this mm_struct is on lru_gen_mm_list */
@@ -1105,7 +1185,8 @@ enum vm_fault_reason {
        { VM_FAULT_RETRY,               "RETRY" },      \
        { VM_FAULT_FALLBACK,            "FALLBACK" },   \
        { VM_FAULT_DONE_COW,            "DONE_COW" },   \
-       { VM_FAULT_NEEDDSYNC,           "NEEDDSYNC" }
+       { VM_FAULT_NEEDDSYNC,           "NEEDDSYNC" },  \
+       { VM_FAULT_COMPLETED,           "COMPLETED" }
 
 struct vm_special_mapping {
        const char *name;       /* The name, e.g. "[vdso]". */
@@ -1139,14 +1220,6 @@ enum tlb_flush_reason {
        NR_TLB_FLUSH_REASONS,
 };
 
- /*
-  * A swap entry has to fit into a "unsigned long", as the entry is hidden
-  * in the "index" field of the swapper address space.
-  */
-typedef struct {
-       unsigned long val;
-} swp_entry_t;
-
 /**
  * enum fault_flag - Fault flag definitions.
  * @FAULT_FLAG_WRITE: Fault was a write fault.