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

mm: remove folio_pincount_ptr() and head_compound_pincount()

We can use folio->_pincount directly, since all users are guarded by tests
of compound/large.

Link: https://lkml.kernel.org/r/20230111142915.1001531-2-willy@infradead.org
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Reviewed-by: John Hubbard <jhubbard@nvidia.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Matthew Wilcox (Oracle) and committed by
Andrew Morton
94688e8e 7d4a8be0

+30 -43
+12 -13
Documentation/core-api/pin_user_pages.rst
··· 55 55 pages* array, and the function then pins pages by incrementing each by a special 56 56 value: GUP_PIN_COUNTING_BIAS. 57 57 58 - For compound pages, the GUP_PIN_COUNTING_BIAS scheme is not used. Instead, 59 - an exact form of pin counting is achieved, by using the 2nd struct page 60 - in the compound page. A new struct page field, compound_pincount, has 61 - been added in order to support this. 58 + For large folios, the GUP_PIN_COUNTING_BIAS scheme is not used. Instead, 59 + the extra space available in the struct folio is used to store the 60 + pincount directly. 62 61 63 - This approach for compound pages avoids the counting upper limit problems that 64 - are discussed below. Those limitations would have been aggravated severely by 65 - huge pages, because each tail page adds a refcount to the head page. And in 66 - fact, testing revealed that, without a separate compound_pincount field, 67 - page overflows were seen in some huge page stress tests. 62 + This approach for large folios avoids the counting upper limit problems 63 + that are discussed below. Those limitations would have been aggravated 64 + severely by huge pages, because each tail page adds a refcount to the 65 + head page. And in fact, testing revealed that, without a separate pincount 66 + field, refcount overflows were seen in some huge page stress tests. 68 67 69 - This also means that huge pages and compound pages do not suffer 68 + This also means that huge pages and large folios do not suffer 70 69 from the false positives problem that is mentioned below.:: 71 70 72 71 Function ··· 263 264 Other diagnostics 264 265 ================= 265 266 266 - dump_page() has been enhanced slightly, to handle these new counting 267 - fields, and to better report on compound pages in general. Specifically, 268 - for compound pages, the exact (compound_pincount) pincount is reported. 267 + dump_page() has been enhanced slightly to handle these new counting 268 + fields, and to better report on large folios in general. Specifically, 269 + for large folios, the exact pincount is reported. 269 270 270 271 References 271 272 ==========
+2 -12
include/linux/mm.h
··· 1011 1011 1012 1012 void destroy_large_folio(struct folio *folio); 1013 1013 1014 - static inline int head_compound_pincount(struct page *head) 1015 - { 1016 - return atomic_read(compound_pincount_ptr(head)); 1017 - } 1018 - 1019 1014 static inline void set_compound_order(struct page *page, unsigned int order) 1020 1015 { 1021 1016 page[1].compound_order = order; ··· 1636 1641 return page_folio(pfn_to_page(pfn)); 1637 1642 } 1638 1643 1639 - static inline atomic_t *folio_pincount_ptr(struct folio *folio) 1640 - { 1641 - return &folio_page(folio, 1)->compound_pincount; 1642 - } 1643 - 1644 1644 /** 1645 1645 * folio_maybe_dma_pinned - Report if a folio may be pinned for DMA. 1646 1646 * @folio: The folio. ··· 1653 1663 * expected to be able to deal gracefully with a false positive. 1654 1664 * 1655 1665 * For large folios, the result will be exactly correct. That's because 1656 - * we have more tracking data available: the compound_pincount is used 1666 + * we have more tracking data available: the _pincount field is used 1657 1667 * instead of the GUP_PIN_COUNTING_BIAS scheme. 1658 1668 * 1659 1669 * For more information, please see Documentation/core-api/pin_user_pages.rst. ··· 1664 1674 static inline bool folio_maybe_dma_pinned(struct folio *folio) 1665 1675 { 1666 1676 if (folio_test_large(folio)) 1667 - return atomic_read(folio_pincount_ptr(folio)) > 0; 1677 + return atomic_read(&folio->_pincount) > 0; 1668 1678 1669 1679 /* 1670 1680 * folio_ref_count() is signed. If that refcount overflows, then
-5
include/linux/mm_types.h
··· 443 443 return &page[1].subpages_mapcount; 444 444 } 445 445 446 - static inline atomic_t *compound_pincount_ptr(struct page *page) 447 - { 448 - return &page[1].compound_pincount; 449 - } 450 - 451 446 /* 452 447 * Used for sizing the vmemmap region on some architectures 453 448 */
+2 -2
mm/debug.c
··· 94 94 page, page_ref_count(head), mapcount, mapping, 95 95 page_to_pgoff(page), page_to_pfn(page)); 96 96 if (compound) { 97 - pr_warn("head:%p order:%u compound_mapcount:%d subpages_mapcount:%d compound_pincount:%d\n", 97 + pr_warn("head:%p order:%u compound_mapcount:%d subpages_mapcount:%d pincount:%d\n", 98 98 head, compound_order(head), 99 99 head_compound_mapcount(head), 100 100 head_subpages_mapcount(head), 101 - head_compound_pincount(head)); 101 + atomic_read(&folio->_pincount)); 102 102 } 103 103 104 104 #ifdef CONFIG_MEMCG
+4 -4
mm/gup.c
··· 111 111 * FOLL_GET: folio's refcount will be incremented by @refs. 112 112 * 113 113 * FOLL_PIN on large folios: folio's refcount will be incremented by 114 - * @refs, and its compound_pincount will be incremented by @refs. 114 + * @refs, and its pincount will be incremented by @refs. 115 115 * 116 116 * FOLL_PIN on single-page folios: folio's refcount will be incremented by 117 117 * @refs * GUP_PIN_COUNTING_BIAS. ··· 157 157 * try_get_folio() is left intact. 158 158 */ 159 159 if (folio_test_large(folio)) 160 - atomic_add(refs, folio_pincount_ptr(folio)); 160 + atomic_add(refs, &folio->_pincount); 161 161 else 162 162 folio_ref_add(folio, 163 163 refs * (GUP_PIN_COUNTING_BIAS - 1)); ··· 182 182 if (flags & FOLL_PIN) { 183 183 node_stat_mod_folio(folio, NR_FOLL_PIN_RELEASED, refs); 184 184 if (folio_test_large(folio)) 185 - atomic_sub(refs, folio_pincount_ptr(folio)); 185 + atomic_sub(refs, &folio->_pincount); 186 186 else 187 187 refs *= GUP_PIN_COUNTING_BIAS; 188 188 } ··· 232 232 */ 233 233 if (folio_test_large(folio)) { 234 234 folio_ref_add(folio, 1); 235 - atomic_add(1, folio_pincount_ptr(folio)); 235 + atomic_add(1, &folio->_pincount); 236 236 } else { 237 237 folio_ref_add(folio, GUP_PIN_COUNTING_BIAS); 238 238 }
+2 -2
mm/huge_memory.c
··· 2477 2477 * of swap cache pages that store the swp_entry_t in tail pages. 2478 2478 * Fix up and warn once if private is unexpectedly set. 2479 2479 * 2480 - * What of 32-bit systems, on which head[1].compound_pincount overlays 2480 + * What of 32-bit systems, on which folio->_pincount overlays 2481 2481 * head[1].private? No problem: THP_SWAP is not enabled on 32-bit, and 2482 - * compound_pincount must be 0 for folio_ref_freeze() to have succeeded. 2482 + * pincount must be 0 for folio_ref_freeze() to have succeeded. 2483 2483 */ 2484 2484 if (!folio_test_swapcache(page_folio(head))) { 2485 2485 VM_WARN_ON_ONCE_PAGE(page_tail->private != 0, page_tail);
+2 -2
mm/hugetlb.c
··· 1476 1476 1477 1477 atomic_set(folio_mapcount_ptr(folio), 0); 1478 1478 atomic_set(folio_subpages_mapcount_ptr(folio), 0); 1479 - atomic_set(folio_pincount_ptr(folio), 0); 1479 + atomic_set(&folio->_pincount, 0); 1480 1480 1481 1481 for (i = 1; i < nr_pages; i++) { 1482 1482 p = folio_page(folio, i); ··· 1998 1998 } 1999 1999 atomic_set(folio_mapcount_ptr(folio), -1); 2000 2000 atomic_set(folio_subpages_mapcount_ptr(folio), 0); 2001 - atomic_set(folio_pincount_ptr(folio), 0); 2001 + atomic_set(&folio->_pincount, 0); 2002 2002 return true; 2003 2003 2004 2004 out_error:
+6 -3
mm/page_alloc.c
··· 775 775 776 776 static void prep_compound_head(struct page *page, unsigned int order) 777 777 { 778 + struct folio *folio = (struct folio *)page; 779 + 778 780 set_compound_page_dtor(page, COMPOUND_PAGE_DTOR); 779 781 set_compound_order(page, order); 780 782 atomic_set(compound_mapcount_ptr(page), -1); 781 783 atomic_set(subpages_mapcount_ptr(page), 0); 782 - atomic_set(compound_pincount_ptr(page), 0); 784 + atomic_set(&folio->_pincount, 0); 783 785 } 784 786 785 787 static void prep_compound_tail(struct page *head, int tail_idx) ··· 1293 1291 1294 1292 static int free_tail_pages_check(struct page *head_page, struct page *page) 1295 1293 { 1294 + struct folio *folio = (struct folio *)head_page; 1296 1295 int ret = 1; 1297 1296 1298 1297 /* ··· 1317 1314 bad_page(page, "nonzero subpages_mapcount"); 1318 1315 goto out; 1319 1316 } 1320 - if (unlikely(head_compound_pincount(head_page))) { 1321 - bad_page(page, "nonzero compound_pincount"); 1317 + if (unlikely(atomic_read(&folio->_pincount))) { 1318 + bad_page(page, "nonzero pincount"); 1322 1319 goto out; 1323 1320 } 1324 1321 break;