To be able to easily maintain pools of pages mapped uncached or write-combined, TTM doesn't use shmem directly for buffer object memory, but on shrinking, page contents are backed up to shmem objects so that the content later can be swapped out.
At shrink time that puts some strain on the memory reserves. To copy a high-order page, one either has to dip far into the kernel reserves (one high-order page size) before any memory can be released, or one can chose to split the high-order page into order 0 pages and free them as soon as they are copied. The latter approach is used by TTM but that tends to fragment higher-order pages. One approach to get around this is to insert the higher-order pages directly into shmem objects, so that if CONFIG_THP_SWAP is enabled, they can be swapped out without splitting. And at shrink time there will be no additional memory allocation save for the shmem radix tree allocations. Add a shmem interface to insert isolated pages, with enough asserts to avoid a user of the interface inserting pages confusing shmem. Then make TTM use that interface. As an alternative, one could add an interface to insert pages directly into the swap cache, but since the swap cache doesn't seem intended for inserting pages for which we don't immediately schedule a writeout, the shmem approach was chosen. Thomas Hellström (2): mm/shmem: add shmem_insert_folio() drm/ttm: Use ttm_backup_insert_folio() for zero-copy swapout drivers/gpu/drm/ttm/ttm_backup.c | 92 ++++++++++----------------- drivers/gpu/drm/ttm/ttm_pool.c | 67 ++++++++++++++------ include/drm/ttm/ttm_backup.h | 11 ++-- include/linux/mm.h | 1 + include/linux/shmem_fs.h | 2 + mm/page_alloc.c | 21 +++++++ mm/shmem.c | 105 +++++++++++++++++++++++++++++++ 7 files changed, 216 insertions(+), 83 deletions(-) -- 2.54.0
