]> www.infradead.org Git - nvme.git/commitdiff
mm: add tail private fields to struct folio
authorMatthew Wilcox (Oracle) <willy@infradead.org>
Wed, 16 Aug 2023 15:12:00 +0000 (16:12 +0100)
committerAndrew Morton <akpm@linux-foundation.org>
Mon, 21 Aug 2023 21:28:45 +0000 (14:28 -0700)
Because THP_SWAP uses page->private for each page, we must not use the
space which overlaps that field for anything which would conflict with
that.  We avoid the conflict on 32-bit systems by disallowing THP_SWAP on
32-bit.

Link: https://lkml.kernel.org/r/20230816151201.3655946-13-willy@infradead.org
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: David Hildenbrand <david@redhat.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Sidhartha Kumar <sidhartha.kumar@oracle.com>
Cc: Yanteng Si <siyanteng@loongson.cn>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
include/linux/mm_types.h

index 40afb3bbc309db40a8b541cdcb70cb134607312a..06e9315bfe7cf591879f8f44d46640f28676a73d 100644 (file)
@@ -322,8 +322,11 @@ struct folio {
                        atomic_t _pincount;
 #ifdef CONFIG_64BIT
                        unsigned int _folio_nr_pages;
-#endif
+                       /* 4 byte gap here */
        /* private: the union with struct page is transitional */
+                       /* Fix THP_SWAP to not use tail->private */
+                       unsigned long _private_1;
+#endif
                };
                struct page __page_1;
        };
@@ -344,6 +347,9 @@ struct folio {
        /* public: */
                        struct list_head _deferred_list;
        /* private: the union with struct page is transitional */
+                       unsigned long _avail_2a;
+                       /* Fix THP_SWAP to not use tail->private */
+                       unsigned long _private_2a;
                };
                struct page __page_2;
        };
@@ -368,12 +374,18 @@ FOLIO_MATCH(memcg_data, memcg_data);
                        offsetof(struct page, pg) + sizeof(struct page))
 FOLIO_MATCH(flags, _flags_1);
 FOLIO_MATCH(compound_head, _head_1);
+#ifdef CONFIG_64BIT
+FOLIO_MATCH(private, _private_1);
+#endif
 #undef FOLIO_MATCH
 #define FOLIO_MATCH(pg, fl)                                            \
        static_assert(offsetof(struct folio, fl) ==                     \
                        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);
+FOLIO_MATCH(private, _private_2a);
 #undef FOLIO_MATCH
 
 /**