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

mm/lru: Convert __pagevec_lru_add_fn to take a folio

This saves five calls to compound_head(), totalling 60 bytes of text.

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: David Howells <dhowells@redhat.com>
Acked-by: Vlastimil Babka <vbabka@suse.cz>

+41 -40
+16 -16
include/trace/events/pagemap.h
··· 16 16 #define PAGEMAP_MAPPEDDISK 0x0020u 17 17 #define PAGEMAP_BUFFERS 0x0040u 18 18 19 - #define trace_pagemap_flags(page) ( \ 20 - (PageAnon(page) ? PAGEMAP_ANONYMOUS : PAGEMAP_FILE) | \ 21 - (page_mapped(page) ? PAGEMAP_MAPPED : 0) | \ 22 - (PageSwapCache(page) ? PAGEMAP_SWAPCACHE : 0) | \ 23 - (PageSwapBacked(page) ? PAGEMAP_SWAPBACKED : 0) | \ 24 - (PageMappedToDisk(page) ? PAGEMAP_MAPPEDDISK : 0) | \ 25 - (page_has_private(page) ? PAGEMAP_BUFFERS : 0) \ 19 + #define trace_pagemap_flags(folio) ( \ 20 + (folio_test_anon(folio) ? PAGEMAP_ANONYMOUS : PAGEMAP_FILE) | \ 21 + (folio_mapped(folio) ? PAGEMAP_MAPPED : 0) | \ 22 + (folio_test_swapcache(folio) ? PAGEMAP_SWAPCACHE : 0) | \ 23 + (folio_test_swapbacked(folio) ? PAGEMAP_SWAPBACKED : 0) | \ 24 + (folio_test_mappedtodisk(folio) ? PAGEMAP_MAPPEDDISK : 0) | \ 25 + (folio_test_private(folio) ? PAGEMAP_BUFFERS : 0) \ 26 26 ) 27 27 28 28 TRACE_EVENT(mm_lru_insertion, 29 29 30 - TP_PROTO(struct page *page), 30 + TP_PROTO(struct folio *folio), 31 31 32 - TP_ARGS(page), 32 + TP_ARGS(folio), 33 33 34 34 TP_STRUCT__entry( 35 - __field(struct page *, page ) 35 + __field(struct folio *, folio ) 36 36 __field(unsigned long, pfn ) 37 37 __field(enum lru_list, lru ) 38 38 __field(unsigned long, flags ) 39 39 ), 40 40 41 41 TP_fast_assign( 42 - __entry->page = page; 43 - __entry->pfn = page_to_pfn(page); 44 - __entry->lru = folio_lru_list(page_folio(page)); 45 - __entry->flags = trace_pagemap_flags(page); 42 + __entry->folio = folio; 43 + __entry->pfn = folio_pfn(folio); 44 + __entry->lru = folio_lru_list(folio); 45 + __entry->flags = trace_pagemap_flags(folio); 46 46 ), 47 47 48 48 /* Flag format is based on page-types.c formatting for pagemap */ 49 - TP_printk("page=%p pfn=0x%lx lru=%d flags=%s%s%s%s%s%s", 50 - __entry->page, 49 + TP_printk("folio=%p pfn=0x%lx lru=%d flags=%s%s%s%s%s%s", 50 + __entry->folio, 51 51 __entry->pfn, 52 52 __entry->lru, 53 53 __entry->flags & PAGEMAP_MAPPED ? "M" : " ",
+25 -24
mm/swap.c
··· 992 992 } 993 993 EXPORT_SYMBOL(__pagevec_release); 994 994 995 - static void __pagevec_lru_add_fn(struct page *page, struct lruvec *lruvec) 995 + static void __pagevec_lru_add_fn(struct folio *folio, struct lruvec *lruvec) 996 996 { 997 - int was_unevictable = TestClearPageUnevictable(page); 998 - int nr_pages = thp_nr_pages(page); 997 + int was_unevictable = folio_test_clear_unevictable(folio); 998 + long nr_pages = folio_nr_pages(folio); 999 999 1000 - VM_BUG_ON_PAGE(PageLRU(page), page); 1000 + VM_BUG_ON_FOLIO(folio_test_lru(folio), folio); 1001 1001 1002 1002 /* 1003 - * Page becomes evictable in two ways: 1003 + * A folio becomes evictable in two ways: 1004 1004 * 1) Within LRU lock [munlock_vma_page() and __munlock_pagevec()]. 1005 - * 2) Before acquiring LRU lock to put the page to correct LRU and then 1005 + * 2) Before acquiring LRU lock to put the folio on the correct LRU 1006 + * and then 1006 1007 * a) do PageLRU check with lock [check_move_unevictable_pages] 1007 1008 * b) do PageLRU check before lock [clear_page_mlock] 1008 1009 * ··· 1012 1011 * 1013 1012 * #0: __pagevec_lru_add_fn #1: clear_page_mlock 1014 1013 * 1015 - * SetPageLRU() TestClearPageMlocked() 1014 + * folio_set_lru() folio_test_clear_mlocked() 1016 1015 * smp_mb() // explicit ordering // above provides strict 1017 1016 * // ordering 1018 - * PageMlocked() PageLRU() 1017 + * folio_test_mlocked() folio_test_lru() 1019 1018 * 1020 1019 * 1021 - * if '#1' does not observe setting of PG_lru by '#0' and fails 1022 - * isolation, the explicit barrier will make sure that page_evictable 1023 - * check will put the page in correct LRU. Without smp_mb(), SetPageLRU 1024 - * can be reordered after PageMlocked check and can make '#1' to fail 1025 - * the isolation of the page whose Mlocked bit is cleared (#0 is also 1026 - * looking at the same page) and the evictable page will be stranded 1027 - * in an unevictable LRU. 1020 + * if '#1' does not observe setting of PG_lru by '#0' and 1021 + * fails isolation, the explicit barrier will make sure that 1022 + * folio_evictable check will put the folio on the correct 1023 + * LRU. Without smp_mb(), folio_set_lru() can be reordered 1024 + * after folio_test_mlocked() check and can make '#1' fail the 1025 + * isolation of the folio whose mlocked bit is cleared (#0 is 1026 + * also looking at the same folio) and the evictable folio will 1027 + * be stranded on an unevictable LRU. 1028 1028 */ 1029 - SetPageLRU(page); 1029 + folio_set_lru(folio); 1030 1030 smp_mb__after_atomic(); 1031 1031 1032 - if (page_evictable(page)) { 1032 + if (folio_evictable(folio)) { 1033 1033 if (was_unevictable) 1034 1034 __count_vm_events(UNEVICTABLE_PGRESCUED, nr_pages); 1035 1035 } else { 1036 - ClearPageActive(page); 1037 - SetPageUnevictable(page); 1036 + folio_clear_active(folio); 1037 + folio_set_unevictable(folio); 1038 1038 if (!was_unevictable) 1039 1039 __count_vm_events(UNEVICTABLE_PGCULLED, nr_pages); 1040 1040 } 1041 1041 1042 - add_page_to_lru_list(page, lruvec); 1043 - trace_mm_lru_insertion(page); 1042 + lruvec_add_folio(lruvec, folio); 1043 + trace_mm_lru_insertion(folio); 1044 1044 } 1045 1045 1046 1046 /* ··· 1055 1053 unsigned long flags = 0; 1056 1054 1057 1055 for (i = 0; i < pagevec_count(pvec); i++) { 1058 - struct page *page = pvec->pages[i]; 1059 - struct folio *folio = page_folio(page); 1056 + struct folio *folio = page_folio(pvec->pages[i]); 1060 1057 1061 1058 lruvec = folio_lruvec_relock_irqsave(folio, lruvec, &flags); 1062 - __pagevec_lru_add_fn(page, lruvec); 1059 + __pagevec_lru_add_fn(folio, lruvec); 1063 1060 } 1064 1061 if (lruvec) 1065 1062 unlock_page_lruvec_irqrestore(lruvec, flags);