All of lore.kernel.org
 help / color / mirror / Atom feed
From: kernel test robot <lkp@intel.com>
To: Dev Jain <dev.jain@arm.com>,
	akpm@linux-foundation.org, david@kernel.org, ljs@kernel.org
Cc: oe-kbuild-all@lists.linux.dev, Dev Jain <dev.jain@arm.com>,
	riel@surriel.com, liam@infradead.org, vbabka@kernel.org,
	harry@kernel.org, jannh@google.com, kas@kernel.org,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org,
	ryan.roberts@arm.com, anshuman.khandual@arm.com,
	stable@vger.kernel.org
Subject: Re: [PATCH] mm/rmap: use huge_ptep_get() in try_to_unmap_one()
Date: Thu, 25 Jun 2026 13:45:57 +0800	[thread overview]
Message-ID: <202606251311.CCKYInqf-lkp@intel.com> (raw)
In-Reply-To: <20260625042853.2752898-1-dev.jain@arm.com>

Hi Dev,

kernel test robot noticed the following build errors:

[auto build test ERROR on akpm-mm/mm-everything]

url:    https://github.com/intel-lab-lkp/linux/commits/Dev-Jain/mm-rmap-use-huge_ptep_get-in-try_to_unmap_one/20260625-123050
base:   https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
patch link:    https://lore.kernel.org/r/20260625042853.2752898-1-dev.jain%40arm.com
patch subject: [PATCH] mm/rmap: use huge_ptep_get() in try_to_unmap_one()
config: nios2-allnoconfig (https://download.01.org/0day-ci/archive/20260625/202606251311.CCKYInqf-lkp@intel.com/config)
compiler: nios2-linux-gcc (GCC) 11.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260625/202606251311.CCKYInqf-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/202606251311.CCKYInqf-lkp@intel.com/

All errors (new ones prefixed by >>):

   mm/rmap.c: In function 'try_to_unmap_one':
>> mm/rmap.c:2100:34: error: implicit declaration of function 'huge_ptep_get' [-Werror=implicit-function-declaration]
    2100 |                         pteval = huge_ptep_get(mm, address, pvmw.pte);
         |                                  ^~~~~~~~~~~~~
>> mm/rmap.c:2100:34: error: incompatible types when assigning to type 'pte_t' from type 'int'
   cc1: some warnings being treated as errors


vim +/huge_ptep_get +2100 mm/rmap.c

  1980	
  1981	/*
  1982	 * @arg: enum ttu_flags will be passed to this argument
  1983	 */
  1984	static bool try_to_unmap_one(struct folio *folio, struct vm_area_struct *vma,
  1985			     unsigned long address, void *arg)
  1986	{
  1987		struct mm_struct *mm = vma->vm_mm;
  1988		DEFINE_FOLIO_VMA_WALK(pvmw, folio, vma, address, 0);
  1989		bool anon_exclusive, ret = true;
  1990		pte_t pteval;
  1991		struct page *subpage;
  1992		struct mmu_notifier_range range;
  1993		enum ttu_flags flags = (enum ttu_flags)(long)arg;
  1994		unsigned long nr_pages = 1, end_addr;
  1995		unsigned long pfn;
  1996		unsigned long hsz = 0;
  1997		int ptes = 0;
  1998	
  1999		/*
  2000		 * When racing against e.g. zap_pte_range() on another cpu,
  2001		 * in between its ptep_get_and_clear_full() and folio_remove_rmap_*(),
  2002		 * try_to_unmap() may return before folio_mapped() has become false,
  2003		 * if page table locking is skipped: use TTU_SYNC to wait for that.
  2004		 */
  2005		if (flags & TTU_SYNC)
  2006			pvmw.flags = PVMW_SYNC;
  2007	
  2008		/*
  2009		 * For THP, we have to assume the worse case ie pmd for invalidation.
  2010		 * For hugetlb, it could be much worse if we need to do pud
  2011		 * invalidation in the case of pmd sharing.
  2012		 *
  2013		 * Note that the folio can not be freed in this function as call of
  2014		 * try_to_unmap() must hold a reference on the folio.
  2015		 */
  2016		range.end = vma_address_end(&pvmw);
  2017		mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, vma->vm_mm,
  2018					address, range.end);
  2019		if (folio_test_hugetlb(folio)) {
  2020			/*
  2021			 * If sharing is possible, start and end will be adjusted
  2022			 * accordingly.
  2023			 */
  2024			adjust_range_if_pmd_sharing_possible(vma, &range.start,
  2025							     &range.end);
  2026	
  2027			/* We need the huge page size for set_huge_pte_at() */
  2028			hsz = huge_page_size(hstate_vma(vma));
  2029		}
  2030		mmu_notifier_invalidate_range_start(&range);
  2031	
  2032		while (page_vma_mapped_walk(&pvmw)) {
  2033			nr_pages = 1;
  2034	
  2035			/*
  2036			 * If the folio is in an mlock()d vma, we must not swap it out.
  2037			 */
  2038			if (!(flags & TTU_IGNORE_MLOCK) &&
  2039			    (vma->vm_flags & VM_LOCKED)) {
  2040				ptes++;
  2041	
  2042				/*
  2043				 * Set 'ret' to indicate the page cannot be unmapped.
  2044				 *
  2045				 * Do not jump to walk_abort immediately as additional
  2046				 * iteration might be required to detect fully mapped
  2047				 * folio an mlock it.
  2048				 */
  2049				ret = false;
  2050	
  2051				/* Only mlock fully mapped pages */
  2052				if (pvmw.pte && ptes != pvmw.nr_pages)
  2053					continue;
  2054	
  2055				/*
  2056				 * All PTEs must be protected by page table lock in
  2057				 * order to mlock the page.
  2058				 *
  2059				 * If page table boundary has been cross, current ptl
  2060				 * only protect part of ptes.
  2061				 */
  2062				if (pvmw.flags & PVMW_PGTABLE_CROSSED)
  2063					goto walk_done;
  2064	
  2065				/* Restore the mlock which got missed */
  2066				mlock_vma_folio(folio, vma);
  2067				goto walk_done;
  2068			}
  2069	
  2070			if (!pvmw.pte) {
  2071				if (folio_test_lazyfree(folio)) {
  2072					if (unmap_huge_pmd_locked(vma, pvmw.address, pvmw.pmd, folio))
  2073						goto walk_done;
  2074					/*
  2075					 * unmap_huge_pmd_locked has either already marked
  2076					 * the folio as swap-backed or decided to retain it
  2077					 * due to GUP or speculative references.
  2078					 */
  2079					goto walk_abort;
  2080				}
  2081	
  2082				if (flags & TTU_SPLIT_HUGE_PMD) {
  2083					/*
  2084					 * We temporarily have to drop the PTL and
  2085					 * restart so we can process the PTE-mapped THP.
  2086					 */
  2087					split_huge_pmd_locked(vma, pvmw.address,
  2088							      pvmw.pmd, false);
  2089					flags &= ~TTU_SPLIT_HUGE_PMD;
  2090					page_vma_mapped_walk_restart(&pvmw);
  2091					continue;
  2092				}
  2093			}
  2094	
  2095			/* Unexpected PMD-mapped THP? */
  2096			VM_BUG_ON_FOLIO(!pvmw.pte, folio);
  2097	
  2098			address = pvmw.address;
  2099			if (folio_test_hugetlb(folio)) {
> 2100				pteval = huge_ptep_get(mm, address, pvmw.pte);
  2101			} else {
  2102				/*
  2103				 * Handle PFN swap PTEs, such as device-exclusive ones,
  2104				 * that actually map pages.
  2105				 */
  2106				pteval = ptep_get(pvmw.pte);
  2107			}
  2108			if (likely(pte_present(pteval))) {
  2109				pfn = pte_pfn(pteval);
  2110			} else {
  2111				const softleaf_t entry = softleaf_from_pte(pteval);
  2112	
  2113				pfn = softleaf_to_pfn(entry);
  2114				VM_WARN_ON_FOLIO(folio_test_hugetlb(folio), folio);
  2115			}
  2116	
  2117			subpage = folio_page(folio, pfn - folio_pfn(folio));
  2118			anon_exclusive = folio_test_anon(folio) &&
  2119					 PageAnonExclusive(subpage);
  2120	
  2121			if (folio_test_hugetlb(folio)) {
  2122				bool anon = folio_test_anon(folio);
  2123	
  2124				/*
  2125				 * The try_to_unmap() is only passed a hugetlb page
  2126				 * in the case where the hugetlb page is poisoned.
  2127				 */
  2128				VM_BUG_ON_PAGE(!PageHWPoison(subpage), subpage);
  2129				/*
  2130				 * huge_pmd_unshare may unmap an entire PMD page.
  2131				 * There is no way of knowing exactly which PMDs may
  2132				 * be cached for this mm, so we must flush them all.
  2133				 * start/end were already adjusted above to cover this
  2134				 * range.
  2135				 */
  2136				flush_cache_range(vma, range.start, range.end);
  2137	
  2138				/*
  2139				 * To call huge_pmd_unshare, i_mmap_rwsem must be
  2140				 * held in write mode.  Caller needs to explicitly
  2141				 * do this outside rmap routines.
  2142				 *
  2143				 * We also must hold hugetlb vma_lock in write mode.
  2144				 * Lock order dictates acquiring vma_lock BEFORE
  2145				 * i_mmap_rwsem.  We can only try lock here and fail
  2146				 * if unsuccessful.
  2147				 */
  2148				if (!anon) {
  2149					struct mmu_gather tlb;
  2150	
  2151					VM_BUG_ON(!(flags & TTU_RMAP_LOCKED));
  2152					if (!hugetlb_vma_trylock_write(vma))
  2153						goto walk_abort;
  2154	
  2155					tlb_gather_mmu_vma(&tlb, vma);
  2156					if (huge_pmd_unshare(&tlb, vma, address, pvmw.pte)) {
  2157						hugetlb_vma_unlock_write(vma);
  2158						huge_pmd_unshare_flush(&tlb, vma);
  2159						tlb_finish_mmu(&tlb);
  2160						/*
  2161						 * The PMD table was unmapped,
  2162						 * consequently unmapping the folio.
  2163						 */
  2164						goto walk_done;
  2165					}
  2166					hugetlb_vma_unlock_write(vma);
  2167					tlb_finish_mmu(&tlb);
  2168				}
  2169				pteval = huge_ptep_clear_flush(vma, address, pvmw.pte);
  2170				if (pte_dirty(pteval))
  2171					folio_mark_dirty(folio);
  2172			} else if (likely(pte_present(pteval))) {
  2173				nr_pages = folio_unmap_pte_batch(folio, &pvmw, flags, pteval);
  2174				end_addr = address + nr_pages * PAGE_SIZE;
  2175				flush_cache_range(vma, address, end_addr);
  2176	
  2177				/* Nuke the page table entry. */
  2178				pteval = get_and_clear_ptes(mm, address, pvmw.pte, nr_pages);
  2179				/*
  2180				 * We clear the PTE but do not flush so potentially
  2181				 * a remote CPU could still be writing to the folio.
  2182				 * If the entry was previously clean then the
  2183				 * architecture must guarantee that a clear->dirty
  2184				 * transition on a cached TLB entry is written through
  2185				 * and traps if the PTE is unmapped.
  2186				 */
  2187				if (should_defer_flush(mm, flags))
  2188					set_tlb_ubc_flush_pending(mm, pteval, address, end_addr);
  2189				else
  2190					flush_tlb_range(vma, address, end_addr);
  2191				if (pte_dirty(pteval))
  2192					folio_mark_dirty(folio);
  2193			} else {
  2194				pte_clear(mm, address, pvmw.pte);
  2195			}
  2196	
  2197			/*
  2198			 * Now the pte is cleared. If this pte was uffd-wp armed,
  2199			 * we may want to replace a none pte with a marker pte if
  2200			 * it's file-backed, so we don't lose the tracking info.
  2201			 */
  2202			pte_install_uffd_wp_if_needed(vma, address, pvmw.pte, pteval);
  2203	
  2204			/* Update high watermark before we lower rss */
  2205			update_hiwater_rss(mm);
  2206	
  2207			if (PageHWPoison(subpage) && (flags & TTU_HWPOISON)) {
  2208				pteval = swp_entry_to_pte(make_hwpoison_entry(subpage));
  2209				if (folio_test_hugetlb(folio)) {
  2210					hugetlb_count_sub(folio_nr_pages(folio), mm);
  2211					set_huge_pte_at(mm, address, pvmw.pte, pteval,
  2212							hsz);
  2213				} else {
  2214					dec_mm_counter(mm, mm_counter(folio));
  2215					set_pte_at(mm, address, pvmw.pte, pteval);
  2216				}
  2217			} else if (likely(pte_present(pteval)) && pte_unused(pteval) &&
  2218				   !userfaultfd_armed(vma)) {
  2219				/*
  2220				 * The guest indicated that the page content is of no
  2221				 * interest anymore. Simply discard the pte, vmscan
  2222				 * will take care of the rest.
  2223				 * A future reference will then fault in a new zero
  2224				 * page. When userfaultfd is active, we must not drop
  2225				 * this page though, as its main user (postcopy
  2226				 * migration) will not expect userfaults on already
  2227				 * copied pages.
  2228				 */
  2229				dec_mm_counter(mm, mm_counter(folio));
  2230			} else if (folio_test_anon(folio)) {
  2231				swp_entry_t entry = page_swap_entry(subpage);
  2232				pte_t swp_pte;
  2233				/*
  2234				 * Store the swap location in the pte.
  2235				 * See handle_pte_fault() ...
  2236				 */
  2237				if (unlikely(folio_test_swapbacked(folio) !=
  2238						folio_test_swapcache(folio))) {
  2239					WARN_ON_ONCE(1);
  2240					goto walk_abort;
  2241				}
  2242	
  2243				/* MADV_FREE page check */
  2244				if (!folio_test_swapbacked(folio)) {
  2245					int ref_count, map_count;
  2246	
  2247					/*
  2248					 * Synchronize with gup_pte_range():
  2249					 * - clear PTE; barrier; read refcount
  2250					 * - inc refcount; barrier; read PTE
  2251					 */
  2252					smp_mb();
  2253	
  2254					ref_count = folio_ref_count(folio);
  2255					map_count = folio_mapcount(folio);
  2256	
  2257					/*
  2258					 * Order reads for page refcount and dirty flag
  2259					 * (see comments in __remove_mapping()).
  2260					 */
  2261					smp_rmb();
  2262	
  2263					if (folio_test_dirty(folio) && !(vma->vm_flags & VM_DROPPABLE)) {
  2264						/*
  2265						 * redirtied either using the page table or a previously
  2266						 * obtained GUP reference.
  2267						 */
  2268						set_ptes(mm, address, pvmw.pte, pteval, nr_pages);
  2269						folio_set_swapbacked(folio);
  2270						goto walk_abort;
  2271					} else if (ref_count != 1 + map_count) {
  2272						/*
  2273						 * Additional reference. Could be a GUP reference or any
  2274						 * speculative reference. GUP users must mark the folio
  2275						 * dirty if there was a modification. This folio cannot be
  2276						 * reclaimed right now either way, so act just like nothing
  2277						 * happened.
  2278						 * We'll come back here later and detect if the folio was
  2279						 * dirtied when the additional reference is gone.
  2280						 */
  2281						set_ptes(mm, address, pvmw.pte, pteval, nr_pages);
  2282						goto walk_abort;
  2283					}
  2284					add_mm_counter(mm, MM_ANONPAGES, -nr_pages);
  2285					goto discard;
  2286				}
  2287	
  2288				if (folio_dup_swap(folio, subpage) < 0) {
  2289					set_pte_at(mm, address, pvmw.pte, pteval);
  2290					goto walk_abort;
  2291				}
  2292	
  2293				/*
  2294				 * arch_unmap_one() is expected to be a NOP on
  2295				 * architectures where we could have PFN swap PTEs,
  2296				 * so we'll not check/care.
  2297				 */
  2298				if (arch_unmap_one(mm, vma, address, pteval) < 0) {
  2299					folio_put_swap(folio, subpage);
  2300					set_pte_at(mm, address, pvmw.pte, pteval);
  2301					goto walk_abort;
  2302				}
  2303	
  2304				/* See folio_try_share_anon_rmap(): clear PTE first. */
  2305				if (anon_exclusive &&
  2306				    folio_try_share_anon_rmap_pte(folio, subpage)) {
  2307					folio_put_swap(folio, subpage);
  2308					set_pte_at(mm, address, pvmw.pte, pteval);
  2309					goto walk_abort;
  2310				}
  2311				if (list_empty(&mm->mmlist)) {
  2312					spin_lock(&mmlist_lock);
  2313					if (list_empty(&mm->mmlist))
  2314						list_add(&mm->mmlist, &init_mm.mmlist);
  2315					spin_unlock(&mmlist_lock);
  2316				}
  2317				dec_mm_counter(mm, MM_ANONPAGES);
  2318				inc_mm_counter(mm, MM_SWAPENTS);
  2319				swp_pte = swp_entry_to_pte(entry);
  2320				if (anon_exclusive)
  2321					swp_pte = pte_swp_mkexclusive(swp_pte);
  2322				if (likely(pte_present(pteval))) {
  2323					if (pte_soft_dirty(pteval))
  2324						swp_pte = pte_swp_mksoft_dirty(swp_pte);
  2325					if (pte_uffd_wp(pteval))
  2326						swp_pte = pte_swp_mkuffd_wp(swp_pte);
  2327				} else {
  2328					if (pte_swp_soft_dirty(pteval))
  2329						swp_pte = pte_swp_mksoft_dirty(swp_pte);
  2330					if (pte_swp_uffd_wp(pteval))
  2331						swp_pte = pte_swp_mkuffd_wp(swp_pte);
  2332				}
  2333				set_pte_at(mm, address, pvmw.pte, swp_pte);
  2334			} else {
  2335				/*
  2336				 * This is a locked file-backed folio,
  2337				 * so it cannot be removed from the page
  2338				 * cache and replaced by a new folio before
  2339				 * mmu_notifier_invalidate_range_end, so no
  2340				 * concurrent thread might update its page table
  2341				 * to point at a new folio while a device is
  2342				 * still using this folio.
  2343				 *
  2344				 * See Documentation/mm/mmu_notifier.rst
  2345				 */
  2346				add_mm_counter(mm, mm_counter_file(folio), -nr_pages);
  2347			}
  2348	discard:
  2349			if (unlikely(folio_test_hugetlb(folio))) {
  2350				hugetlb_remove_rmap(folio);
  2351			} else {
  2352				folio_remove_rmap_ptes(folio, subpage, nr_pages, vma);
  2353			}
  2354			if (vma->vm_flags & VM_LOCKED)
  2355				mlock_drain_local();
  2356			folio_put_refs(folio, nr_pages);
  2357	
  2358			/*
  2359			 * If we are sure that we batched the entire folio and cleared
  2360			 * all PTEs, we can just optimize and stop right here.
  2361			 */
  2362			if (nr_pages == folio_nr_pages(folio))
  2363				goto walk_done;
  2364			continue;
  2365	walk_abort:
  2366			ret = false;
  2367	walk_done:
  2368			page_vma_mapped_walk_done(&pvmw);
  2369			break;
  2370		}
  2371	
  2372		mmu_notifier_invalidate_range_end(&range);
  2373	
  2374		return ret;
  2375	}
  2376	

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


  parent reply	other threads:[~2026-06-25  5:46 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-25  4:28 [PATCH] mm/rmap: use huge_ptep_get() in try_to_unmap_one() Dev Jain
2026-06-25  4:42 ` Andrew Morton
2026-06-25  5:06   ` Dev Jain
2026-06-25  5:45 ` kernel test robot [this message]
2026-06-25  5:45 ` kernel test robot
2026-06-25  6:59   ` Dev Jain
2026-06-25  7:54     ` David Hildenbrand (Arm)
2026-06-25  7:56 ` David Hildenbrand (Arm)
2026-06-25  8:03   ` Dev Jain
2026-06-25  8:28     ` David Hildenbrand (Arm)
2026-06-25  8:40       ` Dev Jain

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=202606251311.CCKYInqf-lkp@intel.com \
    --to=lkp@intel.com \
    --cc=akpm@linux-foundation.org \
    --cc=anshuman.khandual@arm.com \
    --cc=david@kernel.org \
    --cc=dev.jain@arm.com \
    --cc=harry@kernel.org \
    --cc=jannh@google.com \
    --cc=kas@kernel.org \
    --cc=liam@infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=ljs@kernel.org \
    --cc=oe-kbuild-all@lists.linux.dev \
    --cc=riel@surriel.com \
    --cc=ryan.roberts@arm.com \
    --cc=stable@vger.kernel.org \
    --cc=vbabka@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.