Commit b10ff04d authored by Matthew Wilcox (Oracle)'s avatar Matthew Wilcox (Oracle) Committed by Andrew Morton

mm: add tail private fields to struct folio

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.orgSigned-off-by: default avatarMatthew 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: default avatarAndrew Morton <akpm@linux-foundation.org>
parent 6199277b
...@@ -322,8 +322,11 @@ struct folio { ...@@ -322,8 +322,11 @@ struct folio {
atomic_t _pincount; atomic_t _pincount;
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
unsigned int _folio_nr_pages; unsigned int _folio_nr_pages;
#endif /* 4 byte gap here */
/* private: the union with struct page is transitional */ /* 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; struct page __page_1;
}; };
...@@ -344,6 +347,9 @@ struct folio { ...@@ -344,6 +347,9 @@ struct folio {
/* public: */ /* public: */
struct list_head _deferred_list; struct list_head _deferred_list;
/* private: the union with struct page is transitional */ /* 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; struct page __page_2;
}; };
...@@ -368,12 +374,18 @@ FOLIO_MATCH(memcg_data, memcg_data); ...@@ -368,12 +374,18 @@ FOLIO_MATCH(memcg_data, memcg_data);
offsetof(struct page, pg) + sizeof(struct page)) offsetof(struct page, pg) + sizeof(struct page))
FOLIO_MATCH(flags, _flags_1); FOLIO_MATCH(flags, _flags_1);
FOLIO_MATCH(compound_head, _head_1); FOLIO_MATCH(compound_head, _head_1);
#ifdef CONFIG_64BIT
FOLIO_MATCH(private, _private_1);
#endif
#undef FOLIO_MATCH #undef FOLIO_MATCH
#define FOLIO_MATCH(pg, fl) \ #define FOLIO_MATCH(pg, fl) \
static_assert(offsetof(struct folio, fl) == \ static_assert(offsetof(struct folio, fl) == \
offsetof(struct page, pg) + 2 * sizeof(struct page)) offsetof(struct page, pg) + 2 * sizeof(struct page))
FOLIO_MATCH(flags, _flags_2); FOLIO_MATCH(flags, _flags_2);
FOLIO_MATCH(compound_head, _head_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 #undef FOLIO_MATCH
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment