summaryrefslogtreecommitdiff
path: root/include/linux/timerqueue.h
diff options
context:
space:
mode:
authorZi Yan <ziy@nvidia.com>2026-09-20 22:27:57 -0400
committerAndrew Morton <akpm@linux-foundation.org>2026-10-08 22:55:14 -0700
commitc315da11e3272d5026b613b933a48016f3af3a18 (patch)
treeabbe401179cdd8f9796f259cd7e6904556483e3b /include/linux/timerqueue.h
parent9b20271285898e993c6a540aae6291af755da05a (diff)
downloadlinux-c315da11e3272d5026b613b933a48016f3af3a18.tar.gz
linux-c315da11e3272d5026b613b933a48016f3af3a18.zip
mm/zsmalloc: replace PG_private with pointer comparison
Patch series "Remove PG_private by using page/folio->private checks instead", v5. This patchset removes PG_private to make space for upcoming PG_folio for identifying pages from a folio (more details in Note below). Instead of checking PG_private, all code is changed to check page/folio->private != NULL instead. Overview === Most code uses folio_attach/detach/change_private() functions, so folio refcount is increased and decreased when folio->private is set and reset, respectively. There is no need to change them. Changes are needed for exceptional users: 1. zsmalloc uses PG_private to indicate first component zpdesc page and page->private is used to store zspage in zpdesc. To remove PG_private, is_first_zpdesc() is replaced by pointer comparison. 2. kernel/events/ring_buffer.c stores page order in page->private. Replacing PG_private with page->private != NULL works. 3. drivers/xen/grant-table.c stores xen_page_foreign in page->private, where on 32-bit, a pointer to xen_page_foreign is stored; on 64-bit, page->private is used as xen_page_foreign. PG_private check is replaced by page->private != NULL on 32-bit for xen_page_foreign deallocation. On 64-bit, page->private is cleared unconditionally since {domid=0, gref=0} (xen_page_foreign can be 0) is valid. 4. fs/crypto/crypto.c stores a folio pointer in page->private, PG_private checks are replaced by page->private != NULL. 5. fs/erofs has two different uses: 5a. folio->private is used to form a reversed list of the outputs of readahead_folio(). readahead_folio_last() is added to output folios in reversed order, so that ->private is no longer needed. 5b. folio->private is used as an in-flight I/O counter. Convert the code to use folio_attach/detach/get_private() and add bias==1 to the counter to avoid folio->private being zero. 6. fs/nfs/write.c: folio refcount maintenance is in a bigger scope than folio->private. So folio_attach/detach/get_private() is not used. Nothing to change. 7. fs/f2fs uses attach_page_private() to first reset folio->private then immediately sets PAGE_PRIVATE_NOT_POINTER bit on it. Change it to use attach_page_private() to set PAGE_PRIVATE_NOT_POINTER bit directly to avoid folio->private == NULL gap inside set_page_private_##name(). 8. hugetlb uses folio_change_private(folio, NULL) without folio refcount maintenance. Change it to folio->private = NULL. After the above changes, PG_private ops are converted to page/folio->private ops. folio_has_attached_private() is added to check filesystem-only private data by excluding swapcache and hugetlb folios, because swapcache folios overlap swp_entry_t swap with ->private and hugetlb sets its own flags in ->private. Note === 1. KPF_PRIVATE is removed after PG_private is removed. 2. Documentation/mm/hugetlbfs_reserv.rst is outdated, so I did not remove PG_private related text. It should be rewritten. 3. PG_folio is planned to be set on every page from a folio in page_rmappable_folio(), so folios with any order (currently PG_large_rmappable is used to identify >0 order folios, but not order-0 folios) can be identified. Then vm_insert_*() can correctly reject all folios and rmap code will only see folios. Eventually, page_folio() will return NULL for non-folio pages by checking PG_folio, but before that all existing users that treat compound pages as folios will need to be converted. This patch (of 17): zsmalloc uses PG_private to indicate first zpdesc in a zspage chain. It is equivalent to check zpdesc == zspage->first_zpdesc. Replace is_first_zpdesc() with zpdesc == zspage->first_zpdesc in obj_allocated(). For get_first_zpdesc(), first_zpdesc is from zspage->first_zpdesc, so replace is_first_zpdesc() with first_zpdesc->zspage == zspage, the second requirement of a zspage chain, where all zpdescs point to the same zspage. is_first_zpdesc(), is only used in VM_BUG_ON_PAGE(), so performance impact should be negligible. While at it, change VM_BUG_ON() to VM_WARN_ON_ONCE_PAGE(). It prepares for a future commit that remove PG_private. No functional change intended. Link: https://lore.kernel.org/20260920-remove-pg_private-v5-0-bb68b6a21869@nvidia.com Link: https://lore.kernel.org/20260920-remove-pg_private-v5-1-bb68b6a21869@nvidia.com Signed-off-by: Zi Yan <ziy@nvidia.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Acked-by: Johannes Weiner <hannes@cmpxchg.org> Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org> Acked-by: David Hildenbrand (Arm) <david@kernel.org> Reviewed-by: Lance Yang <lance.yang@linux.dev> Assisted-by: LLM Cc: Minchan Kim <minchan@kernel.org>
Diffstat (limited to 'include/linux/timerqueue.h')
0 files changed, 0 insertions, 0 deletions