mm,thp,rmap: subpages_mapcount COMPOUND_MAPPED if PMD-mapped
[sfrench/cifs-2.6.git] / include / linux / mm.h
index 84fb91f6f56eb5f8c079d3d3ad046a83b14b750a..d33639be3db3ea899301afa9238dc8785586c4fb 100644 (file)
@@ -836,13 +836,22 @@ static inline int head_compound_mapcount(struct page *head)
        return atomic_read(compound_mapcount_ptr(head)) + 1;
 }
 
+/*
+ * If a 16GB hugetlb page were mapped by PTEs of all of its 4kB sub-pages,
+ * its subpages_mapcount would be 0x400000: choose the COMPOUND_MAPPED bit
+ * above that range, instead of 2*(PMD_SIZE/PAGE_SIZE).  Hugetlb currently
+ * leaves subpages_mapcount at 0, but avoid surprise if it participates later.
+ */
+#define COMPOUND_MAPPED        0x800000
+#define SUBPAGES_MAPPED        (COMPOUND_MAPPED - 1)
+
 /*
  * Number of sub-pages mapped by PTE, does not include compound mapcount.
  * Must be called only on head of compound page.
  */
 static inline int head_subpages_mapcount(struct page *head)
 {
-       return atomic_read(subpages_mapcount_ptr(head));
+       return atomic_read(subpages_mapcount_ptr(head)) & SUBPAGES_MAPPED;
 }
 
 /*
@@ -902,8 +911,12 @@ static inline int total_mapcount(struct page *page)
 
 static inline bool folio_large_is_mapped(struct folio *folio)
 {
-       return atomic_read(folio_mapcount_ptr(folio)) +
-               atomic_read(folio_subpages_mapcount_ptr(folio)) >= 0;
+       /*
+        * Reading folio_mapcount_ptr() below could be omitted if hugetlb
+        * participated in incrementing subpages_mapcount when compound mapped.
+        */
+       return atomic_read(folio_subpages_mapcount_ptr(folio)) > 0 ||
+               atomic_read(folio_mapcount_ptr(folio)) >= 0;
 }
 
 /**