Building the Linux kernel with Clang and LLVM
 help / color / mirror / Atom feed
* [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
@ 2026-08-18 19:35 kernel test robot
  0 siblings, 0 replies; only message in thread
From: kernel test robot @ 2026-08-18 19:35 UTC (permalink / raw)
  To: Kiryl Shutsemau (Meta); +Cc: llvm, oe-kbuild-all

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/202608190330.FdsN6Kj3-lkp@intel.com/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/202608190330.FdsN6Kj3-lkp@intel.com/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 <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202608190330.FdsN6Kj3-lkp@intel.com/

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

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2026-08-18 19:36 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-18 19:35 [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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox