[kas:collapse/rfc-v1 27/76] mm/collapse.c:302:29: error: call to undeclared function 'folio_test_young'; ISO C99 and later do not support implicit function declarations
kernel test robot <[email protected]>
| Newsgroups | dev.linux.lists.llvm,dev.linux.lists.oe-kbuild-all |
|---|---|
| Message-ID | <[email protected]> |
tree: https://git.kernel.org/pub/scm/linux/kernel/git/kas/linux.git collapse/rfc-v1 head: efac4ce42bf9ea34a32d1563fe3370ee837a751f commit: cb521dbfccdeb167af52e321f0396a75be2796a9 [27/76] mm/collapse: scan a table for what a collapse could use config: i386-buildonly-randconfig-002-20260818 (https://download.01.org/0day-ci/archive/20260819/[email protected]/config) compiler: clang version 22.1.3 (https://github.com/llvm/llvm-project e9846648fd6183ee6d8cbdb4502213fcf902a211) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260819/[email protected]/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <[email protected]> | Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/ All errors (new ones prefixed by >>): In file included from mm/collapse.c:8: In file included from include/linux/leafops.h:11: include/linux/swapops.h:88:21: error: use of undeclared identifier 'MAX_SWAPFILES_SHIFT' 88 | ret.val = (type << SWP_TYPE_SHIFT) | (offset & SWP_OFFSET_MASK); | ^~~~~~~~~~~~~~ include/linux/swapops.h:27:45: note: expanded from macro 'SWP_TYPE_SHIFT' 27 | #define SWP_TYPE_SHIFT (BITS_PER_XA_VALUE - MAX_SWAPFILES_SHIFT) | ^~~~~~~~~~~~~~~~~~~ include/linux/swapops.h:88:49: error: use of undeclared identifier 'MAX_SWAPFILES_SHIFT' 88 | ret.val = (type << SWP_TYPE_SHIFT) | (offset & SWP_OFFSET_MASK); | ^~~~~~~~~~~~~~~ include/linux/swapops.h:28:34: note: expanded from macro 'SWP_OFFSET_MASK' 28 | #define SWP_OFFSET_MASK ((1UL << SWP_TYPE_SHIFT) - 1) | ^~~~~~~~~~~~~~ include/linux/swapops.h:27:45: note: expanded from macro 'SWP_TYPE_SHIFT' 27 | #define SWP_TYPE_SHIFT (BITS_PER_XA_VALUE - MAX_SWAPFILES_SHIFT) | ^~~~~~~~~~~~~~~~~~~ include/linux/swapops.h:98:23: error: use of undeclared identifier 'MAX_SWAPFILES_SHIFT' 98 | return (entry.val >> SWP_TYPE_SHIFT); | ^~~~~~~~~~~~~~ include/linux/swapops.h:27:45: note: expanded from macro 'SWP_TYPE_SHIFT' 27 | #define SWP_TYPE_SHIFT (BITS_PER_XA_VALUE - MAX_SWAPFILES_SHIFT) | ^~~~~~~~~~~~~~~~~~~ include/linux/swapops.h:107:21: error: use of undeclared identifier 'MAX_SWAPFILES_SHIFT' 107 | return entry.val & SWP_OFFSET_MASK; | ^~~~~~~~~~~~~~~ include/linux/swapops.h:28:34: note: expanded from macro 'SWP_OFFSET_MASK' 28 | #define SWP_OFFSET_MASK ((1UL << SWP_TYPE_SHIFT) - 1) | ^~~~~~~~~~~~~~ include/linux/swapops.h:27:45: note: expanded from macro 'SWP_TYPE_SHIFT' 27 | #define SWP_TYPE_SHIFT (BITS_PER_XA_VALUE - MAX_SWAPFILES_SHIFT) | ^~~~~~~~~~~~~~~~~~~ include/linux/swapops.h:173:19: error: use of undeclared identifier 'SWP_MIGRATION_READ'; did you mean 'THP_MIGRATION_FAIL'? 173 | return swp_entry(SWP_MIGRATION_READ, offset); | ^~~~~~~~~~~~~~~~~~ | THP_MIGRATION_FAIL include/linux/vm_event_item.h:62:3: note: 'THP_MIGRATION_FAIL' declared here 62 | THP_MIGRATION_FAIL, | ^ In file included from mm/collapse.c:8: In file included from include/linux/leafops.h:11: include/linux/swapops.h:178:19: error: use of undeclared identifier 'SWP_MIGRATION_READ_EXCLUSIVE' 178 | return swp_entry(SWP_MIGRATION_READ_EXCLUSIVE, offset); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/swapops.h:183:19: error: use of undeclared identifier 'SWP_MIGRATION_WRITE' 183 | return swp_entry(SWP_MIGRATION_WRITE, offset); | ^~~~~~~~~~~~~~~~~~~ include/linux/swapops.h:204:26: error: use of undeclared identifier 'MAX_SWAPFILES_SHIFT' 204 | swp_offset(entry) | SWP_MIG_YOUNG); | ^~~~~~~~~~~~~ include/linux/swapops.h:66:29: note: expanded from macro 'SWP_MIG_YOUNG' 66 | #define SWP_MIG_YOUNG BIT(SWP_MIG_YOUNG_BIT) | ^~~~~~~~~~~~~~~~~ include/linux/swapops.h:62:29: note: expanded from macro 'SWP_MIG_YOUNG_BIT' 62 | #define SWP_MIG_YOUNG_BIT (SWP_PFN_BITS) | ^~~~~~~~~~~~ include/linux/swapops.h:40:11: note: expanded from macro 'SWP_PFN_BITS' 40 | SWP_TYPE_SHIFT) | ^~~~~~~~~~~~~~ include/linux/swapops.h:27:45: note: expanded from macro 'SWP_TYPE_SHIFT' 27 | #define SWP_TYPE_SHIFT (BITS_PER_XA_VALUE - MAX_SWAPFILES_SHIFT) | ^~~~~~~~~~~~~~~~~~~ include/linux/swapops.h:212:26: error: use of undeclared identifier 'MAX_SWAPFILES_SHIFT' 212 | swp_offset(entry) | SWP_MIG_DIRTY); | ^~~~~~~~~~~~~ include/linux/swapops.h:67:29: note: expanded from macro 'SWP_MIG_DIRTY' 67 | #define SWP_MIG_DIRTY BIT(SWP_MIG_DIRTY_BIT) | ^~~~~~~~~~~~~~~~~ include/linux/swapops.h:63:29: note: expanded from macro 'SWP_MIG_DIRTY_BIT' 63 | #define SWP_MIG_DIRTY_BIT (SWP_PFN_BITS + 1) | ^~~~~~~~~~~~ include/linux/swapops.h:40:11: note: expanded from macro 'SWP_PFN_BITS' 40 | SWP_TYPE_SHIFT) | ^~~~~~~~~~~~~~ include/linux/swapops.h:27:45: note: expanded from macro 'SWP_TYPE_SHIFT' 27 | #define SWP_TYPE_SHIFT (BITS_PER_XA_VALUE - MAX_SWAPFILES_SHIFT) | ^~~~~~~~~~~~~~~~~~~ include/linux/swapops.h:260:19: error: use of undeclared identifier 'SWP_HWPOISON'; did you mean 'FOLL_HWPOISON'? 260 | return swp_entry(SWP_HWPOISON, page_to_pfn(page)); | ^~~~~~~~~~~~ | FOLL_HWPOISON include/linux/mm_types.h:1904:2: note: 'FOLL_HWPOISON' declared here 1904 | FOLL_HWPOISON = 1 << 6, | ^ In file included from mm/collapse.c:8: In file included from include/linux/leafops.h:11: include/linux/swapops.h:265:28: error: use of undeclared identifier 'SWP_HWPOISON'; did you mean 'FOLL_HWPOISON'? 265 | return swp_type(entry) == SWP_HWPOISON; | ^~~~~~~~~~~~ | FOLL_HWPOISON include/linux/mm_types.h:1904:2: note: 'FOLL_HWPOISON' declared here 1904 | FOLL_HWPOISON = 1 << 6, | ^ In file included from mm/collapse.c:8: In file included from include/linux/leafops.h:11: include/linux/swapops.h:304:19: error: use of undeclared identifier 'SWP_PTE_MARKER' 304 | return swp_entry(SWP_PTE_MARKER, marker); | ^~~~~~~~~~~~~~ >> mm/collapse.c:302:29: error: call to undeclared function 'folio_test_young'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] 302 | (pte_young(pteval) || folio_test_young(folio) || | ^ 13 errors generated. vim +/folio_test_young +302 mm/collapse.c 102 103 /* 104 * Scan the PTEs between @start and @end and record what a collapse could use: a 105 * bit in cc->eligible_ptes for every PTE that may be a source. Returns 106 * SCAN_SUCCEED when every PTE in the range qualified, otherwise the reason one 107 * did not, and narrows cc->select_orders to what is still worth trying here. 108 */ 109 static enum scan_result collapse_scan_table(struct vm_area_struct *vma, 110 pmd_t *pmd, unsigned long start, 111 unsigned long end, 112 struct collapse_control *cc) 113 { 114 const unsigned long pmd_addr = start & HPAGE_PMD_MASK; 115 unsigned int max_ptes_none, max_ptes_swap, max_ptes_shared; 116 int none_or_zero = 0, shared = 0, referenced = 0, unmapped = 0; 117 enum scan_result result, pmd_result = SCAN_SUCCEED; 118 unsigned int first_offset; 119 unsigned long addr; 120 pte_t *pte; 121 int i; 122 123 max_ptes_none = collapse_max_ptes_none(cc, vma, HPAGE_PMD_ORDER); 124 max_ptes_swap = collapse_max_ptes_swap(cc, HPAGE_PMD_ORDER); 125 max_ptes_shared = collapse_max_ptes_shared(cc, HPAGE_PMD_ORDER); 126 127 /* 128 * No page table lock: what this builds is advice, and the freeze settles 129 * every question it asks by re-reading the table under the lock and 130 * freezing each source to the count it expects. A racy read can only 131 * cost a candidate that the freeze then refuses, or miss one that the 132 * next pass finds. What it buys is that a fault in this range does not 133 * wait for a scan of the whole table. 134 * 135 * pte_offset_map() holds rcu_read_lock() until pte_unmap(), which is 136 * what keeps the table itself from being freed underneath the walk; 137 * mmap_lock keeps the VMA attached, without which free_pgtables() could 138 * free it without waiting for RCU at all. Nothing below here sleeps. 139 */ 140 pte = pte_offset_map(pmd, start); 141 if (!pte) { 142 cc->progress++; 143 result = SCAN_NO_PTE_TABLE; 144 goto out_no_table; 145 } 146 147 /* 148 * The bitmap and the selection offsets stay relative to the table: 149 * natural-alignment math needs the table-absolute position, not the 150 * position within an arbitrarily placed VMA. 151 */ 152 first_offset = (start - pmd_addr) >> PAGE_SHIFT; 153 for (i = first_offset, addr = start; addr < end; 154 i++, addr += PAGE_SIZE) { 155 pte_t pteval = ptep_get(pte + (i - first_offset)); 156 struct folio *folio; 157 struct page *page; 158 int node; 159 160 cc->progress++; 161 162 if (pte_none_or_zero(pteval)) { 163 if (++none_or_zero > max_ptes_none && 164 pmd_result == SCAN_SUCCEED) { 165 pmd_result = SCAN_EXCEED_NONE_PTE; 166 count_vm_event(THP_SCAN_EXCEED_NONE_PTE); 167 count_mthp_stat(HPAGE_PMD_ORDER, 168 MTHP_STAT_COLLAPSE_EXCEED_NONE); 169 } 170 continue; 171 } 172 if (!pte_present(pteval)) { 173 unmapped++; 174 if (collapse_exceeds_limit(unmapped, max_ptes_swap, 175 start, end)) { 176 result = SCAN_EXCEED_SWAP_PTE; 177 count_vm_event(THP_SCAN_EXCEED_SWAP_PTE); 178 count_mthp_stat(HPAGE_PMD_ORDER, 179 MTHP_STAT_COLLAPSE_EXCEED_SWAP); 180 goto out_table_refused; 181 } 182 /* Swap entries armed with uffd-wp are refused too */ 183 if (pte_swp_uffd_any(pteval) && 184 pmd_result == SCAN_SUCCEED) 185 pmd_result = SCAN_PTE_UFFD; 186 continue; 187 } 188 if (pte_uffd(pteval)) { 189 /* 190 * The huge PMD could be marked write protected when any 191 * of the small ones is, but that could deliver 192 * userfaults outside the registered range. Keep it 193 * simple and refuse the PTE. 194 */ 195 if (pmd_result == SCAN_SUCCEED) 196 pmd_result = SCAN_PTE_UFFD; 197 continue; 198 } 199 200 page = vm_normal_page(vma, addr, pteval); 201 if (unlikely(!page) || unlikely(is_zone_device_page(page))) { 202 if (pmd_result == SCAN_SUCCEED) 203 pmd_result = SCAN_PAGE_NULL; 204 continue; 205 } 206 folio = page_folio(page); 207 208 /* 209 * A VM_DROPPABLE VMA keeps the lazyfree property across the 210 * collapse, so there is nothing to preserve by skipping. 211 */ 212 if (cc->policy.skip_lazyfree && 213 !(vma->vm_flags & VM_DROPPABLE) && 214 folio_test_lazyfree(folio) && !pte_dirty(pteval)) { 215 if (pmd_result == SCAN_SUCCEED) 216 pmd_result = SCAN_PAGE_LAZYFREE; 217 continue; 218 } 219 220 if (!folio_test_anon(folio)) { 221 if (pmd_result == SCAN_SUCCEED) 222 pmd_result = SCAN_PAGE_ANON; 223 continue; 224 } 225 226 /* 227 * A page counts as shared if any part of its folio is, which 228 * bounds the cost of CoW-breaking rather than the count of it: 229 * collapse_faultin() unshares on !PageAnonExclusive(), a broader 230 * test -- a page whose fork co-mapper has exited is 231 * single-mapped, so not counted here, yet stays non-exclusive 232 * until a write reuses it. Those are the cheap ones, reused in 233 * place. A page that has to be copied is one this test catches, 234 * so the limit does bound the copying it is there to bound. 235 */ 236 if (folio_maybe_mapped_shared(folio)) { 237 shared++; 238 if (collapse_exceeds_limit(shared, max_ptes_shared, 239 start, end)) { 240 result = SCAN_EXCEED_SHARED_PTE; 241 count_vm_event(THP_SCAN_EXCEED_SHARED_PTE); 242 count_mthp_stat(HPAGE_PMD_ORDER, 243 MTHP_STAT_COLLAPSE_EXCEED_SHARED); 244 goto out_table_refused; 245 } 246 } 247 248 /* 249 * Which node the sources are on decides where the destination is 250 * allocated: the one with the most of them wins. 251 */ 252 node = folio_nid(folio); 253 if (collapse_scan_abort(node, cc)) { 254 result = SCAN_SCAN_ABORT; 255 goto out_table_refused; 256 } 257 cc->node_load[node]++; 258 259 /* 260 * Usually a folio somebody else is already isolating, whose 261 * reference the freeze would refuse anyway. Not exact: one 262 * still on a per-CPU add batch reads the same, and the freeze 263 * drains those before it starts. 264 */ 265 if (!folio_test_lru(folio)) { 266 if (pmd_result == SCAN_SUCCEED) 267 pmd_result = SCAN_PAGE_LRU; 268 continue; 269 } 270 if (folio_test_locked(folio)) { 271 if (pmd_result == SCAN_SUCCEED) 272 pmd_result = SCAN_PAGE_LOCK; 273 continue; 274 } 275 276 /* 277 * A folio whose reference count its mappings do not account for 278 * -- a GUP pin, say -- is refused by the freeze, not here. 279 * folio_expected_ref_count() wants a folio that cannot change 280 * order while it is read, and this walk holds no page table lock 281 * and no folio lock, so a folio splitting underneath it would 282 * have the count read for the wrong size. A reference of our 283 * own would not help: it stops the folio being freed, not split. 284 * 285 * So leave it to the freeze, which reads the table under the 286 * lock and settles the question by freezing each source to the 287 * count it expects. What it costs is a window selected here and 288 * refused there. 289 */ 290 291 /* 292 * Every check passed: this PTE can be a collapse source. The 293 * bit is set last, so a disqualified PTE leaves it clear. 294 */ 295 __set_bit(i, cc->eligible_ptes); 296 297 /* 298 * Whether a range has to look used at all is the caller's 299 * policy, so only a caller that asks gathers the evidence. 300 */ 301 if (cc->policy.require_referenced && > 302 (pte_young(pteval) || folio_test_young(folio) || 303 folio_test_referenced(folio) || 304 mmu_notifier_test_young(vma->vm_mm, addr))) 305 referenced++; 306 } 307 308 if (cc->policy.require_referenced && 309 (!referenced || (unmapped && referenced < HPAGE_PMD_NR / 2))) 310 result = SCAN_LACK_REFERENCED_PAGE; 311 else 312 result = pmd_result; 313 pte_unmap(pte); 314 goto out; 315 316 out_table_refused: 317 /* 318 * The table is refused as a unit -- a limit the whole range exceeds, or 319 * pages on nodes too distant for one folio to serve them all -- so no 320 * window inside it is eligible either. 321 */ 322 pte_unmap(pte); 323 out_no_table: 324 cc->select_orders = 0; 325 out: 326 /* 327 * A PMD candidate needs the whole table, so anything that disqualified a 328 * single PTE rules it out. Smaller windows that avoid the offending 329 * PTEs are still collapsible, so drop just that order and leave the rest 330 * to selection -- dropping it also lowers the order selection roots its 331 * windows at. MADV_COLLAPSE has no other order enabled, so it is left 332 * with none. 333 */ 334 if (result != SCAN_SUCCEED) 335 cc->select_orders &= ~BIT(HPAGE_PMD_ORDER); 336 337 return result; 338 } 339 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki