Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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.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>

authored by

Matthew Wilcox (Oracle) and committed by
Andrew Morton
b10ff04d 6199277b

+13 -1
+13 -1
include/linux/mm_types.h
··· 322 322 atomic_t _pincount; 323 323 #ifdef CONFIG_64BIT 324 324 unsigned int _folio_nr_pages; 325 - #endif 325 + /* 4 byte gap here */ 326 326 /* private: the union with struct page is transitional */ 327 + /* Fix THP_SWAP to not use tail->private */ 328 + unsigned long _private_1; 329 + #endif 327 330 }; 328 331 struct page __page_1; 329 332 }; ··· 347 344 /* public: */ 348 345 struct list_head _deferred_list; 349 346 /* private: the union with struct page is transitional */ 347 + unsigned long _avail_2a; 348 + /* Fix THP_SWAP to not use tail->private */ 349 + unsigned long _private_2a; 350 350 }; 351 351 struct page __page_2; 352 352 }; ··· 374 368 offsetof(struct page, pg) + sizeof(struct page)) 375 369 FOLIO_MATCH(flags, _flags_1); 376 370 FOLIO_MATCH(compound_head, _head_1); 371 + #ifdef CONFIG_64BIT 372 + FOLIO_MATCH(private, _private_1); 373 + #endif 377 374 #undef FOLIO_MATCH 378 375 #define FOLIO_MATCH(pg, fl) \ 379 376 static_assert(offsetof(struct folio, fl) == \ 380 377 offsetof(struct page, pg) + 2 * sizeof(struct page)) 381 378 FOLIO_MATCH(flags, _flags_2); 382 379 FOLIO_MATCH(compound_head, _head_2); 380 + FOLIO_MATCH(flags, _flags_2a); 381 + FOLIO_MATCH(compound_head, _head_2a); 382 + FOLIO_MATCH(private, _private_2a); 383 383 #undef FOLIO_MATCH 384 384 385 385 /**