* [PATCH] mm: bail out when the PMD has been set in bloom filter
@ 2026-02-27 7:52 zhaoyang.huang
2026-02-27 11:42 ` kernel test robot
0 siblings, 1 reply; 2+ messages in thread
From: zhaoyang.huang @ 2026-02-27 7:52 UTC (permalink / raw)
To: Andrew Morton, Yu Zhao, linux-mm, linux-kernel, Zhaoyang Huang,
steve.kang
From: Zhaoyang Huang <zhaoyang.huang@unisoc.com>
There are two reasons to have the recorded PMD bail out from doing
the following iteration
1. It is worth of doing such a trade off thing in terms of reclaiming
efficiency as test_bloom_filter only consume 20~30 instructions in modern
processors(25 instructions in ARM64).
2. The PMD needs to accumulate young pages until aging happens while the
new arrived folio reference checking under current max_seq refuse to do so
which will affect carrying hot PMDs to new generation.
Signed-off-by: Zhaoyang Huang <zhaoyang.huang@unisoc.com>
---
mm/vmscan.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 9d900be478ea..e50e98291d0d 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -4227,6 +4227,10 @@ bool lru_gen_look_around(struct page_vma_mapped_walk *pvmw)
/* avoid taking the LRU lock under the PTL when possible */
walk = current->reclaim_state ? current->reclaim_state->mm_walk : NULL;
+ /* may the pmd has been set in bloom filter */
+ if (test_bloom_filter(mm_state, max_seq, pvmw->pmd))
+ return true;
+
start = max(addr & PMD_MASK, vma->vm_start);
end = min(addr | ~PMD_MASK, vma->vm_end - 1) + 1;
--
2.25.1
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] mm: bail out when the PMD has been set in bloom filter
2026-02-27 7:52 [PATCH] mm: bail out when the PMD has been set in bloom filter zhaoyang.huang
@ 2026-02-27 11:42 ` kernel test robot
0 siblings, 0 replies; 2+ messages in thread
From: kernel test robot @ 2026-02-27 11:42 UTC (permalink / raw)
To: zhaoyang.huang, Andrew Morton, Yu Zhao, linux-kernel,
Zhaoyang Huang, steve.kang
Cc: llvm, oe-kbuild-all, Linux Memory Management List
Hi zhaoyang.huang,
kernel test robot noticed the following build warnings:
[auto build test WARNING on akpm-mm/mm-everything]
url: https://github.com/intel-lab-lkp/linux/commits/zhaoyang-huang/mm-bail-out-when-the-PMD-has-been-set-in-bloom-filter/20260227-155729
base: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
patch link: https://lore.kernel.org/r/20260227075250.1128175-1-zhaoyang.huang%40unisoc.com
patch subject: [PATCH] mm: bail out when the PMD has been set in bloom filter
config: sparc64-randconfig-002-20260227 (https://download.01.org/0day-ci/archive/20260227/202602271916.OBNa34QU-lkp@intel.com/config)
compiler: clang version 23.0.0git (https://github.com/llvm/llvm-project 9a109fbb6e184ec9bcce10615949f598f4c974a9)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260227/202602271916.OBNa34QU-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/202602271916.OBNa34QU-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> mm/vmscan.c:4206:24: warning: variable 'mm_state' is uninitialized when used here [-Wuninitialized]
4206 | if (test_bloom_filter(mm_state, max_seq, pvmw->pmd))
| ^~~~~~~~
mm/vmscan.c:4185:35: note: initialize the variable 'mm_state' to silence this warning
4185 | struct lru_gen_mm_state *mm_state;
| ^
| = NULL
>> mm/vmscan.c:4206:34: warning: variable 'max_seq' is uninitialized when used here [-Wuninitialized]
4206 | if (test_bloom_filter(mm_state, max_seq, pvmw->pmd))
| ^~~~~~~
mm/vmscan.c:4186:23: note: initialize the variable 'max_seq' to silence this warning
4186 | unsigned long max_seq;
| ^
| = 0
2 warnings generated.
vim +/mm_state +4206 mm/vmscan.c
4157
4158 /******************************************************************************
4159 * rmap/PT walk feedback
4160 ******************************************************************************/
4161
4162 /*
4163 * This function exploits spatial locality when shrink_folio_list() walks the
4164 * rmap. It scans the adjacent PTEs of a young PTE and promotes hot pages. If
4165 * the scan was done cacheline efficiently, it adds the PMD entry pointing to
4166 * the PTE table to the Bloom filter. This forms a feedback loop between the
4167 * eviction and the aging.
4168 */
4169 bool lru_gen_look_around(struct page_vma_mapped_walk *pvmw)
4170 {
4171 int i;
4172 bool dirty;
4173 unsigned long start;
4174 unsigned long end;
4175 struct lru_gen_mm_walk *walk;
4176 struct folio *last = NULL;
4177 int young = 1;
4178 pte_t *pte = pvmw->pte;
4179 unsigned long addr = pvmw->address;
4180 struct vm_area_struct *vma = pvmw->vma;
4181 struct folio *folio = pfn_folio(pvmw->pfn);
4182 struct mem_cgroup *memcg;
4183 struct pglist_data *pgdat = folio_pgdat(folio);
4184 struct lruvec *lruvec;
4185 struct lru_gen_mm_state *mm_state;
4186 unsigned long max_seq;
4187 int gen;
4188
4189 lockdep_assert_held(pvmw->ptl);
4190 VM_WARN_ON_ONCE_FOLIO(folio_test_lru(folio), folio);
4191
4192 if (!ptep_clear_young_notify(vma, addr, pte))
4193 return false;
4194
4195 if (spin_is_contended(pvmw->ptl))
4196 return true;
4197
4198 /* exclude special VMAs containing anon pages from COW */
4199 if (vma->vm_flags & VM_SPECIAL)
4200 return true;
4201
4202 /* avoid taking the LRU lock under the PTL when possible */
4203 walk = current->reclaim_state ? current->reclaim_state->mm_walk : NULL;
4204
4205 /* may the pmd has been set in bloom filter */
> 4206 if (test_bloom_filter(mm_state, max_seq, pvmw->pmd))
4207 return true;
4208
4209 start = max(addr & PMD_MASK, vma->vm_start);
4210 end = min(addr | ~PMD_MASK, vma->vm_end - 1) + 1;
4211
4212 if (end - start == PAGE_SIZE)
4213 return true;
4214
4215 if (end - start > MIN_LRU_BATCH * PAGE_SIZE) {
4216 if (addr - start < MIN_LRU_BATCH * PAGE_SIZE / 2)
4217 end = start + MIN_LRU_BATCH * PAGE_SIZE;
4218 else if (end - addr < MIN_LRU_BATCH * PAGE_SIZE / 2)
4219 start = end - MIN_LRU_BATCH * PAGE_SIZE;
4220 else {
4221 start = addr - MIN_LRU_BATCH * PAGE_SIZE / 2;
4222 end = addr + MIN_LRU_BATCH * PAGE_SIZE / 2;
4223 }
4224 }
4225
4226 memcg = get_mem_cgroup_from_folio(folio);
4227 lruvec = mem_cgroup_lruvec(memcg, pgdat);
4228 max_seq = READ_ONCE((lruvec)->lrugen.max_seq);
4229 gen = lru_gen_from_seq(max_seq);
4230 mm_state = get_mm_state(lruvec);
4231
4232 lazy_mmu_mode_enable();
4233
4234 pte -= (addr - start) / PAGE_SIZE;
4235
4236 for (i = 0, addr = start; addr != end; i++, addr += PAGE_SIZE) {
4237 unsigned long pfn;
4238 pte_t ptent = ptep_get(pte + i);
4239
4240 pfn = get_pte_pfn(ptent, vma, addr, pgdat);
4241 if (pfn == -1)
4242 continue;
4243
4244 folio = get_pfn_folio(pfn, memcg, pgdat);
4245 if (!folio)
4246 continue;
4247
4248 if (!ptep_clear_young_notify(vma, addr, pte + i))
4249 continue;
4250
4251 if (last != folio) {
4252 walk_update_folio(walk, last, gen, dirty);
4253
4254 last = folio;
4255 dirty = false;
4256 }
4257
4258 if (pte_dirty(ptent))
4259 dirty = true;
4260
4261 young++;
4262 }
4263
4264 walk_update_folio(walk, last, gen, dirty);
4265
4266 lazy_mmu_mode_disable();
4267
4268 /* feedback from rmap walkers to page table walkers */
4269 if (mm_state && suitable_to_scan(i, young))
4270 update_bloom_filter(mm_state, max_seq, pvmw->pmd);
4271
4272 mem_cgroup_put(memcg);
4273
4274 return true;
4275 }
4276
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-02-27 11:43 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-02-27 7:52 [PATCH] mm: bail out when the PMD has been set in bloom filter zhaoyang.huang
2026-02-27 11:42 ` 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