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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'mm-hotfixes-stable-2024-11-03-10-50' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Pull misc fixes from Andrew Morton:
"17 hotfixes. 9 are cc:stable. 13 are MM and 4 are non-MM.

The usual collection of singletons - please see the changelogs"

* tag 'mm-hotfixes-stable-2024-11-03-10-50' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm:
mm: multi-gen LRU: use {ptep,pmdp}_clear_young_notify()
mm: multi-gen LRU: remove MM_LEAF_OLD and MM_NONLEAF_TOTAL stats
mm, mmap: limit THP alignment of anonymous mappings to PMD-aligned sizes
mm: shrinker: avoid memleak in alloc_shrinker_info
.mailmap: update e-mail address for Eugen Hristev
vmscan,migrate: fix page count imbalance on node stats when demoting pages
mailmap: update Jarkko's email addresses
mm: allow set/clear page_type again
nilfs2: fix potential deadlock with newly created symlinks
Squashfs: fix variable overflow in squashfs_readpage_block
kasan: remove vmalloc_percpu test
tools/mm: -Werror fixes in page-types/slabinfo
mm, swap: avoid over reclaim of full clusters
mm: fix PSWPIN counter for large folios swap-in
mm: avoid VM_BUG_ON when try to map an anon large folio to zero page.
mm/codetag: fix null pointer check logic for ref and tag
mm/gup: stop leaking pinned pages in low memory conditions

+159 -143
+3 -2
.mailmap
··· 199 Enric Balletbo i Serra <eballetbo@kernel.org> <enric.balletbo@collabora.com> 200 Enric Balletbo i Serra <eballetbo@kernel.org> <eballetbo@iseebcn.com> 201 Erik Kaneda <erik.kaneda@intel.com> <erik.schmauss@intel.com> 202 - Eugen Hristev <eugen.hristev@collabora.com> <eugen.hristev@microchip.com> 203 Evgeniy Polyakov <johnpol@2ka.mipt.ru> 204 Ezequiel Garcia <ezequiel@vanguardiasur.com.ar> <ezequiel@collabora.com> 205 Faith Ekstrand <faith.ekstrand@collabora.com> <jason@jlekstrand.net> ··· 283 Jan Kuliga <jtkuliga.kdev@gmail.com> <jankul@alatek.krakow.pl> 284 Jarkko Sakkinen <jarkko@kernel.org> <jarkko.sakkinen@linux.intel.com> 285 Jarkko Sakkinen <jarkko@kernel.org> <jarkko@profian.com> 286 - Jarkko Sakkinen <jarkko@kernel.org> <jarkko.sakkinen@tuni.fi> 287 Jason Gunthorpe <jgg@ziepe.ca> <jgg@mellanox.com> 288 Jason Gunthorpe <jgg@ziepe.ca> <jgg@nvidia.com> 289 Jason Gunthorpe <jgg@ziepe.ca> <jgunthorpe@obsidianresearch.com>
··· 199 Enric Balletbo i Serra <eballetbo@kernel.org> <enric.balletbo@collabora.com> 200 Enric Balletbo i Serra <eballetbo@kernel.org> <eballetbo@iseebcn.com> 201 Erik Kaneda <erik.kaneda@intel.com> <erik.schmauss@intel.com> 202 + Eugen Hristev <eugen.hristev@linaro.org> <eugen.hristev@microchip.com> 203 + Eugen Hristev <eugen.hristev@linaro.org> <eugen.hristev@collabora.com> 204 Evgeniy Polyakov <johnpol@2ka.mipt.ru> 205 Ezequiel Garcia <ezequiel@vanguardiasur.com.ar> <ezequiel@collabora.com> 206 Faith Ekstrand <faith.ekstrand@collabora.com> <jason@jlekstrand.net> ··· 282 Jan Kuliga <jtkuliga.kdev@gmail.com> <jankul@alatek.krakow.pl> 283 Jarkko Sakkinen <jarkko@kernel.org> <jarkko.sakkinen@linux.intel.com> 284 Jarkko Sakkinen <jarkko@kernel.org> <jarkko@profian.com> 285 + Jarkko Sakkinen <jarkko@kernel.org> <jarkko.sakkinen@parity.io> 286 Jason Gunthorpe <jgg@ziepe.ca> <jgg@mellanox.com> 287 Jason Gunthorpe <jgg@ziepe.ca> <jgg@nvidia.com> 288 Jason Gunthorpe <jgg@ziepe.ca> <jgunthorpe@obsidianresearch.com>
+3
fs/nilfs2/namei.c
··· 157 /* slow symlink */ 158 inode->i_op = &nilfs_symlink_inode_operations; 159 inode_nohighmem(inode); 160 inode->i_mapping->a_ops = &nilfs_aops; 161 err = page_symlink(inode, symname, l); 162 if (err)
··· 157 /* slow symlink */ 158 inode->i_op = &nilfs_symlink_inode_operations; 159 inode_nohighmem(inode); 160 + mapping_set_gfp_mask(inode->i_mapping, 161 + mapping_gfp_constraint(inode->i_mapping, 162 + ~__GFP_FS)); 163 inode->i_mapping->a_ops = &nilfs_aops; 164 err = page_symlink(inode, symname, l); 165 if (err)
+5 -4
fs/squashfs/file_direct.c
··· 30 int mask = (1 << (msblk->block_log - PAGE_SHIFT)) - 1; 31 loff_t start_index = folio->index & ~mask; 32 loff_t end_index = start_index | mask; 33 - int i, n, pages, bytes, res = -ENOMEM; 34 struct page **page, *last_page; 35 struct squashfs_page_actor *actor; 36 void *pageaddr; ··· 46 return res; 47 48 /* Try to grab all the pages covered by the Squashfs block */ 49 - for (i = 0, n = start_index; n <= end_index; n++) { 50 - page[i] = (n == folio->index) ? target_page : 51 - grab_cache_page_nowait(target_page->mapping, n); 52 53 if (page[i] == NULL) 54 continue;
··· 30 int mask = (1 << (msblk->block_log - PAGE_SHIFT)) - 1; 31 loff_t start_index = folio->index & ~mask; 32 loff_t end_index = start_index | mask; 33 + loff_t index; 34 + int i, pages, bytes, res = -ENOMEM; 35 struct page **page, *last_page; 36 struct squashfs_page_actor *actor; 37 void *pageaddr; ··· 45 return res; 46 47 /* Try to grab all the pages covered by the Squashfs block */ 48 + for (i = 0, index = start_index; index <= end_index; index++) { 49 + page[i] = (index == folio->index) ? target_page : 50 + grab_cache_page_nowait(target_page->mapping, index); 51 52 if (page[i] == NULL) 53 continue;
+10 -6
include/linux/alloc_tag.h
··· 135 #endif 136 137 /* Caller should verify both ref and tag to be valid */ 138 - static inline void __alloc_tag_ref_set(union codetag_ref *ref, struct alloc_tag *tag) 139 { 140 alloc_tag_add_check(ref, tag); 141 if (!ref || !tag) 142 - return; 143 144 ref->ct = &tag->ct; 145 } 146 147 - static inline void alloc_tag_ref_set(union codetag_ref *ref, struct alloc_tag *tag) 148 { 149 - __alloc_tag_ref_set(ref, tag); 150 /* 151 * We need in increment the call counter every time we have a new 152 * allocation or when we split a large allocation into smaller ones. ··· 157 * counter because when we free each part the counter will be decremented. 158 */ 159 this_cpu_inc(tag->counters->calls); 160 } 161 162 static inline void alloc_tag_add(union codetag_ref *ref, struct alloc_tag *tag, size_t bytes) 163 { 164 - alloc_tag_ref_set(ref, tag); 165 - this_cpu_add(tag->counters->bytes, bytes); 166 } 167 168 static inline void alloc_tag_sub(union codetag_ref *ref, size_t bytes)
··· 135 #endif 136 137 /* Caller should verify both ref and tag to be valid */ 138 + static inline bool __alloc_tag_ref_set(union codetag_ref *ref, struct alloc_tag *tag) 139 { 140 alloc_tag_add_check(ref, tag); 141 if (!ref || !tag) 142 + return false; 143 144 ref->ct = &tag->ct; 145 + return true; 146 } 147 148 + static inline bool alloc_tag_ref_set(union codetag_ref *ref, struct alloc_tag *tag) 149 { 150 + if (unlikely(!__alloc_tag_ref_set(ref, tag))) 151 + return false; 152 + 153 /* 154 * We need in increment the call counter every time we have a new 155 * allocation or when we split a large allocation into smaller ones. ··· 154 * counter because when we free each part the counter will be decremented. 155 */ 156 this_cpu_inc(tag->counters->calls); 157 + return true; 158 } 159 160 static inline void alloc_tag_add(union codetag_ref *ref, struct alloc_tag *tag, size_t bytes) 161 { 162 + if (likely(alloc_tag_ref_set(ref, tag))) 163 + this_cpu_add(tag->counters->bytes, bytes); 164 } 165 166 static inline void alloc_tag_sub(union codetag_ref *ref, size_t bytes)
+3 -4
include/linux/mmzone.h
··· 458 459 enum { 460 MM_LEAF_TOTAL, /* total leaf entries */ 461 - MM_LEAF_OLD, /* old leaf entries */ 462 MM_LEAF_YOUNG, /* young leaf entries */ 463 - MM_NONLEAF_TOTAL, /* total non-leaf entries */ 464 MM_NONLEAF_FOUND, /* non-leaf entries found in Bloom filters */ 465 MM_NONLEAF_ADDED, /* non-leaf entries added to Bloom filters */ 466 NR_MM_STATS ··· 555 556 void lru_gen_init_pgdat(struct pglist_data *pgdat); 557 void lru_gen_init_lruvec(struct lruvec *lruvec); 558 - void lru_gen_look_around(struct page_vma_mapped_walk *pvmw); 559 560 void lru_gen_init_memcg(struct mem_cgroup *memcg); 561 void lru_gen_exit_memcg(struct mem_cgroup *memcg); ··· 574 { 575 } 576 577 - static inline void lru_gen_look_around(struct page_vma_mapped_walk *pvmw) 578 { 579 } 580 581 static inline void lru_gen_init_memcg(struct mem_cgroup *memcg)
··· 458 459 enum { 460 MM_LEAF_TOTAL, /* total leaf entries */ 461 MM_LEAF_YOUNG, /* young leaf entries */ 462 MM_NONLEAF_FOUND, /* non-leaf entries found in Bloom filters */ 463 MM_NONLEAF_ADDED, /* non-leaf entries added to Bloom filters */ 464 NR_MM_STATS ··· 557 558 void lru_gen_init_pgdat(struct pglist_data *pgdat); 559 void lru_gen_init_lruvec(struct lruvec *lruvec); 560 + bool lru_gen_look_around(struct page_vma_mapped_walk *pvmw); 561 562 void lru_gen_init_memcg(struct mem_cgroup *memcg); 563 void lru_gen_exit_memcg(struct mem_cgroup *memcg); ··· 576 { 577 } 578 579 + static inline bool lru_gen_look_around(struct page_vma_mapped_walk *pvmw) 580 { 581 + return false; 582 } 583 584 static inline void lru_gen_init_memcg(struct mem_cgroup *memcg)
+8
include/linux/page-flags.h
··· 975 } \ 976 static __always_inline void __folio_set_##fname(struct folio *folio) \ 977 { \ 978 VM_BUG_ON_FOLIO(data_race(folio->page.page_type) != UINT_MAX, \ 979 folio); \ 980 folio->page.page_type = (unsigned int)PGTY_##lname << 24; \ 981 } \ 982 static __always_inline void __folio_clear_##fname(struct folio *folio) \ 983 { \ 984 VM_BUG_ON_FOLIO(!folio_test_##fname(folio), folio); \ 985 folio->page.page_type = UINT_MAX; \ 986 } ··· 997 } \ 998 static __always_inline void __SetPage##uname(struct page *page) \ 999 { \ 1000 VM_BUG_ON_PAGE(data_race(page->page_type) != UINT_MAX, page); \ 1001 page->page_type = (unsigned int)PGTY_##lname << 24; \ 1002 } \ 1003 static __always_inline void __ClearPage##uname(struct page *page) \ 1004 { \ 1005 VM_BUG_ON_PAGE(!Page##uname(page), page); \ 1006 page->page_type = UINT_MAX; \ 1007 }
··· 975 } \ 976 static __always_inline void __folio_set_##fname(struct folio *folio) \ 977 { \ 978 + if (folio_test_##fname(folio)) \ 979 + return; \ 980 VM_BUG_ON_FOLIO(data_race(folio->page.page_type) != UINT_MAX, \ 981 folio); \ 982 folio->page.page_type = (unsigned int)PGTY_##lname << 24; \ 983 } \ 984 static __always_inline void __folio_clear_##fname(struct folio *folio) \ 985 { \ 986 + if (folio->page.page_type == UINT_MAX) \ 987 + return; \ 988 VM_BUG_ON_FOLIO(!folio_test_##fname(folio), folio); \ 989 folio->page.page_type = UINT_MAX; \ 990 } ··· 993 } \ 994 static __always_inline void __SetPage##uname(struct page *page) \ 995 { \ 996 + if (Page##uname(page)) \ 997 + return; \ 998 VM_BUG_ON_PAGE(data_race(page->page_type) != UINT_MAX, page); \ 999 page->page_type = (unsigned int)PGTY_##lname << 24; \ 1000 } \ 1001 static __always_inline void __ClearPage##uname(struct page *page) \ 1002 { \ 1003 + if (page->page_type == UINT_MAX) \ 1004 + return; \ 1005 VM_BUG_ON_PAGE(!Page##uname(page), page); \ 1006 page->page_type = UINT_MAX; \ 1007 }
+1
include/linux/swap.h
··· 335 * list. 336 */ 337 struct work_struct discard_work; /* discard worker */ 338 struct list_head discard_clusters; /* discard clusters list */ 339 struct plist_node avail_lists[]; /* 340 * entries in swap_avail_heads, one
··· 335 * list. 336 */ 337 struct work_struct discard_work; /* discard worker */ 338 + struct work_struct reclaim_work; /* reclaim worker */ 339 struct list_head discard_clusters; /* discard clusters list */ 340 struct plist_node avail_lists[]; /* 341 * entries in swap_avail_heads, one
+19 -14
mm/gup.c
··· 2394 } 2395 2396 /* 2397 - * Check whether all folios are *allowed* to be pinned indefinitely (longterm). 2398 * Rather confusingly, all folios in the range are required to be pinned via 2399 * FOLL_PIN, before calling this routine. 2400 * 2401 - * If any folios in the range are not allowed to be pinned, then this routine 2402 - * will migrate those folios away, unpin all the folios in the range and return 2403 - * -EAGAIN. The caller should re-pin the entire range with FOLL_PIN and then 2404 - * call this routine again. 2405 * 2406 - * If an error other than -EAGAIN occurs, this indicates a migration failure. 2407 - * The caller should give up, and propagate the error back up the call stack. 2408 - * 2409 - * If everything is OK and all folios in the range are allowed to be pinned, 2410 * then this routine leaves all folios pinned and returns zero for success. 2411 */ 2412 static long check_and_migrate_movable_folios(unsigned long nr_folios, 2413 struct folio **folios) ··· 2430 } 2431 2432 /* 2433 - * This routine just converts all the pages in the @pages array to folios and 2434 - * calls check_and_migrate_movable_folios() to do the heavy lifting. 2435 - * 2436 - * Please see the check_and_migrate_movable_folios() documentation for details. 2437 */ 2438 static long check_and_migrate_movable_pages(unsigned long nr_pages, 2439 struct page **pages) ··· 2440 long i, ret; 2441 2442 folios = kmalloc_array(nr_pages, sizeof(*folios), GFP_KERNEL); 2443 - if (!folios) 2444 return -ENOMEM; 2445 2446 for (i = 0; i < nr_pages; i++) 2447 folios[i] = page_folio(pages[i]);
··· 2394 } 2395 2396 /* 2397 + * Check whether all folios are *allowed* to be pinned indefinitely (long term). 2398 * Rather confusingly, all folios in the range are required to be pinned via 2399 * FOLL_PIN, before calling this routine. 2400 * 2401 + * Return values: 2402 * 2403 + * 0: if everything is OK and all folios in the range are allowed to be pinned, 2404 * then this routine leaves all folios pinned and returns zero for success. 2405 + * 2406 + * -EAGAIN: if any folios in the range are not allowed to be pinned, then this 2407 + * routine will migrate those folios away, unpin all the folios in the range. If 2408 + * migration of the entire set of folios succeeds, then -EAGAIN is returned. The 2409 + * caller should re-pin the entire range with FOLL_PIN and then call this 2410 + * routine again. 2411 + * 2412 + * -ENOMEM, or any other -errno: if an error *other* than -EAGAIN occurs, this 2413 + * indicates a migration failure. The caller should give up, and propagate the 2414 + * error back up the call stack. The caller does not need to unpin any folios in 2415 + * that case, because this routine will do the unpinning. 2416 */ 2417 static long check_and_migrate_movable_folios(unsigned long nr_folios, 2418 struct folio **folios) ··· 2425 } 2426 2427 /* 2428 + * Return values and behavior are the same as those for 2429 + * check_and_migrate_movable_folios(). 2430 */ 2431 static long check_and_migrate_movable_pages(unsigned long nr_pages, 2432 struct page **pages) ··· 2437 long i, ret; 2438 2439 folios = kmalloc_array(nr_pages, sizeof(*folios), GFP_KERNEL); 2440 + if (!folios) { 2441 + unpin_user_pages(pages, nr_pages); 2442 return -ENOMEM; 2443 + } 2444 2445 for (i = 0; i < nr_pages; i++) 2446 folios[i] = page_folio(pages[i]);
-27
mm/kasan/kasan_test_c.c
··· 1810 free_pages((unsigned long)p_ptr, 1); 1811 } 1812 1813 - static void vmalloc_percpu(struct kunit *test) 1814 - { 1815 - char __percpu *ptr; 1816 - int cpu; 1817 - 1818 - /* 1819 - * This test is specifically crafted for the software tag-based mode, 1820 - * the only tag-based mode that poisons percpu mappings. 1821 - */ 1822 - KASAN_TEST_NEEDS_CONFIG_ON(test, CONFIG_KASAN_SW_TAGS); 1823 - 1824 - ptr = __alloc_percpu(PAGE_SIZE, PAGE_SIZE); 1825 - 1826 - for_each_possible_cpu(cpu) { 1827 - char *c_ptr = per_cpu_ptr(ptr, cpu); 1828 - 1829 - KUNIT_EXPECT_GE(test, (u8)get_tag(c_ptr), (u8)KASAN_TAG_MIN); 1830 - KUNIT_EXPECT_LT(test, (u8)get_tag(c_ptr), (u8)KASAN_TAG_KERNEL); 1831 - 1832 - /* Make sure that in-bounds accesses don't crash the kernel. */ 1833 - *c_ptr = 0; 1834 - } 1835 - 1836 - free_percpu(ptr); 1837 - } 1838 - 1839 /* 1840 * Check that the assigned pointer tag falls within the [KASAN_TAG_MIN, 1841 * KASAN_TAG_KERNEL) range (note: excluding the match-all tag) for tag-based ··· 1997 KUNIT_CASE(vmalloc_oob), 1998 KUNIT_CASE(vmap_tags), 1999 KUNIT_CASE(vm_map_ram_tags), 2000 - KUNIT_CASE(vmalloc_percpu), 2001 KUNIT_CASE(match_all_not_assigned), 2002 KUNIT_CASE(match_all_ptr_tag), 2003 KUNIT_CASE(match_all_mem_tag),
··· 1810 free_pages((unsigned long)p_ptr, 1); 1811 } 1812 1813 /* 1814 * Check that the assigned pointer tag falls within the [KASAN_TAG_MIN, 1815 * KASAN_TAG_KERNEL) range (note: excluding the match-all tag) for tag-based ··· 2023 KUNIT_CASE(vmalloc_oob), 2024 KUNIT_CASE(vmap_tags), 2025 KUNIT_CASE(vm_map_ram_tags), 2026 KUNIT_CASE(match_all_not_assigned), 2027 KUNIT_CASE(match_all_ptr_tag), 2028 KUNIT_CASE(match_all_mem_tag),
+3 -2
mm/migrate.c
··· 206 pte_t newpte; 207 void *addr; 208 209 - VM_BUG_ON_PAGE(PageCompound(page), page); 210 VM_BUG_ON_PAGE(!PageAnon(page), page); 211 VM_BUG_ON_PAGE(!PageLocked(page), page); 212 VM_BUG_ON_PAGE(pte_present(*pvmw->pte), page); ··· 1178 * not accounted to NR_ISOLATED_*. They can be recognized 1179 * as __folio_test_movable 1180 */ 1181 - if (likely(!__folio_test_movable(src))) 1182 mod_node_page_state(folio_pgdat(src), NR_ISOLATED_ANON + 1183 folio_is_file_lru(src), -folio_nr_pages(src)); 1184
··· 206 pte_t newpte; 207 void *addr; 208 209 + if (PageCompound(page)) 210 + return false; 211 VM_BUG_ON_PAGE(!PageAnon(page), page); 212 VM_BUG_ON_PAGE(!PageLocked(page), page); 213 VM_BUG_ON_PAGE(pte_present(*pvmw->pte), page); ··· 1177 * not accounted to NR_ISOLATED_*. They can be recognized 1178 * as __folio_test_movable 1179 */ 1180 + if (likely(!__folio_test_movable(src)) && reason != MR_DEMOTION) 1181 mod_node_page_state(folio_pgdat(src), NR_ISOLATED_ANON + 1182 folio_is_file_lru(src), -folio_nr_pages(src)); 1183
+2 -1
mm/mmap.c
··· 900 901 if (get_area) { 902 addr = get_area(file, addr, len, pgoff, flags); 903 - } else if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) { 904 /* Ensures that larger anonymous mappings are THP aligned. */ 905 addr = thp_get_unmapped_area_vmflags(file, addr, len, 906 pgoff, flags, vm_flags);
··· 900 901 if (get_area) { 902 addr = get_area(file, addr, len, pgoff, flags); 903 + } else if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) 904 + && IS_ALIGNED(len, PMD_SIZE)) { 905 /* Ensures that larger anonymous mappings are THP aligned. */ 906 addr = thp_get_unmapped_area_vmflags(file, addr, len, 907 pgoff, flags, vm_flags);
+2 -2
mm/page_io.c
··· 570 * attempt to access it in the page fault retry time check. 571 */ 572 get_task_struct(current); 573 - count_vm_event(PSWPIN); 574 submit_bio_wait(&bio); 575 __end_swap_bio_read(&bio); 576 put_task_struct(current); ··· 585 bio->bi_iter.bi_sector = swap_folio_sector(folio); 586 bio->bi_end_io = end_swap_bio_read; 587 bio_add_folio_nofail(bio, folio, folio_size(folio), 0); 588 - count_vm_event(PSWPIN); 589 submit_bio(bio); 590 } 591
··· 570 * attempt to access it in the page fault retry time check. 571 */ 572 get_task_struct(current); 573 + count_vm_events(PSWPIN, folio_nr_pages(folio)); 574 submit_bio_wait(&bio); 575 __end_swap_bio_read(&bio); 576 put_task_struct(current); ··· 585 bio->bi_iter.bi_sector = swap_folio_sector(folio); 586 bio->bi_end_io = end_swap_bio_read; 587 bio_add_folio_nofail(bio, folio, folio_size(folio), 0); 588 + count_vm_events(PSWPIN, folio_nr_pages(folio)); 589 submit_bio(bio); 590 } 591
+3 -6
mm/rmap.c
··· 885 return false; 886 } 887 888 - if (pvmw.pte) { 889 - if (lru_gen_enabled() && 890 - pte_young(ptep_get(pvmw.pte))) { 891 - lru_gen_look_around(&pvmw); 892 referenced++; 893 - } 894 - 895 if (ptep_clear_flush_young_notify(vma, address, 896 pvmw.pte)) 897 referenced++;
··· 885 return false; 886 } 887 888 + if (lru_gen_enabled() && pvmw.pte) { 889 + if (lru_gen_look_around(&pvmw)) 890 referenced++; 891 + } else if (pvmw.pte) { 892 if (ptep_clear_flush_young_notify(vma, address, 893 pvmw.pte)) 894 referenced++;
+5 -3
mm/shrinker.c
··· 76 77 int alloc_shrinker_info(struct mem_cgroup *memcg) 78 { 79 - struct shrinker_info *info; 80 int nid, ret = 0; 81 int array_size = 0; 82 83 mutex_lock(&shrinker_mutex); 84 array_size = shrinker_unit_size(shrinker_nr_max); 85 for_each_node(nid) { 86 - info = kvzalloc_node(sizeof(*info) + array_size, GFP_KERNEL, nid); 87 if (!info) 88 goto err; 89 info->map_nr_max = shrinker_nr_max; 90 - if (shrinker_unit_alloc(info, NULL, nid)) 91 goto err; 92 rcu_assign_pointer(memcg->nodeinfo[nid]->shrinker_info, info); 93 } 94 mutex_unlock(&shrinker_mutex);
··· 76 77 int alloc_shrinker_info(struct mem_cgroup *memcg) 78 { 79 int nid, ret = 0; 80 int array_size = 0; 81 82 mutex_lock(&shrinker_mutex); 83 array_size = shrinker_unit_size(shrinker_nr_max); 84 for_each_node(nid) { 85 + struct shrinker_info *info = kvzalloc_node(sizeof(*info) + array_size, 86 + GFP_KERNEL, nid); 87 if (!info) 88 goto err; 89 info->map_nr_max = shrinker_nr_max; 90 + if (shrinker_unit_alloc(info, NULL, nid)) { 91 + kvfree(info); 92 goto err; 93 + } 94 rcu_assign_pointer(memcg->nodeinfo[nid]->shrinker_info, info); 95 } 96 mutex_unlock(&shrinker_mutex);
+30 -19
mm/swapfile.c
··· 731 return offset; 732 } 733 734 - static void swap_reclaim_full_clusters(struct swap_info_struct *si) 735 { 736 long to_scan = 1; 737 unsigned long offset, end; 738 struct swap_cluster_info *ci; 739 unsigned char *map = si->swap_map; 740 - int nr_reclaim, total_reclaimed = 0; 741 742 - if (atomic_long_read(&nr_swap_pages) <= SWAPFILE_CLUSTER) 743 to_scan = si->inuse_pages / SWAPFILE_CLUSTER; 744 745 while (!list_empty(&si->full_clusters)) { ··· 750 end = min(si->max, offset + SWAPFILE_CLUSTER); 751 to_scan--; 752 753 while (offset < end) { 754 if (READ_ONCE(map[offset]) == SWAP_HAS_CACHE) { 755 - spin_unlock(&si->lock); 756 nr_reclaim = __try_to_reclaim_swap(si, offset, 757 TTRS_ANYWAY | TTRS_DIRECT); 758 - spin_lock(&si->lock); 759 - if (nr_reclaim > 0) { 760 - offset += nr_reclaim; 761 - total_reclaimed += nr_reclaim; 762 - continue; 763 - } else if (nr_reclaim < 0) { 764 - offset += -nr_reclaim; 765 continue; 766 } 767 } 768 offset++; 769 } 770 - if (to_scan <= 0 || total_reclaimed) 771 break; 772 } 773 } 774 775 /* ··· 808 VM_BUG_ON(!found); 809 goto done; 810 } 811 812 if (order < PMD_ORDER) { 813 unsigned int frags = 0; ··· 894 } 895 896 done: 897 - /* Try reclaim from full clusters if device is nearfull */ 898 - if (vm_swap_full() && (!found || (si->pages - si->inuse_pages) < SWAPFILE_CLUSTER)) { 899 - swap_reclaim_full_clusters(si); 900 - if (!found && !order && si->pages != si->inuse_pages) 901 - goto new_cluster; 902 - } 903 - 904 cluster->next[order] = offset; 905 return found; 906 } ··· 928 si->lowest_bit = si->max; 929 si->highest_bit = 0; 930 del_from_avail_list(si); 931 } 932 } 933 ··· 2825 wait_for_completion(&p->comp); 2826 2827 flush_work(&p->discard_work); 2828 2829 destroy_swap_extents(p); 2830 if (p->flags & SWP_CONTINUED) ··· 3386 return PTR_ERR(si); 3387 3388 INIT_WORK(&si->discard_work, swap_discard_work); 3389 3390 name = getname(specialfile); 3391 if (IS_ERR(name)) {
··· 731 return offset; 732 } 733 734 + /* Return true if reclaimed a whole cluster */ 735 + static void swap_reclaim_full_clusters(struct swap_info_struct *si, bool force) 736 { 737 long to_scan = 1; 738 unsigned long offset, end; 739 struct swap_cluster_info *ci; 740 unsigned char *map = si->swap_map; 741 + int nr_reclaim; 742 743 + if (force) 744 to_scan = si->inuse_pages / SWAPFILE_CLUSTER; 745 746 while (!list_empty(&si->full_clusters)) { ··· 749 end = min(si->max, offset + SWAPFILE_CLUSTER); 750 to_scan--; 751 752 + spin_unlock(&si->lock); 753 while (offset < end) { 754 if (READ_ONCE(map[offset]) == SWAP_HAS_CACHE) { 755 nr_reclaim = __try_to_reclaim_swap(si, offset, 756 TTRS_ANYWAY | TTRS_DIRECT); 757 + if (nr_reclaim) { 758 + offset += abs(nr_reclaim); 759 continue; 760 } 761 } 762 offset++; 763 } 764 + spin_lock(&si->lock); 765 + 766 + if (to_scan <= 0) 767 break; 768 } 769 + } 770 + 771 + static void swap_reclaim_work(struct work_struct *work) 772 + { 773 + struct swap_info_struct *si; 774 + 775 + si = container_of(work, struct swap_info_struct, reclaim_work); 776 + 777 + spin_lock(&si->lock); 778 + swap_reclaim_full_clusters(si, true); 779 + spin_unlock(&si->lock); 780 } 781 782 /* ··· 799 VM_BUG_ON(!found); 800 goto done; 801 } 802 + 803 + /* Try reclaim from full clusters if free clusters list is drained */ 804 + if (vm_swap_full()) 805 + swap_reclaim_full_clusters(si, false); 806 807 if (order < PMD_ORDER) { 808 unsigned int frags = 0; ··· 881 } 882 883 done: 884 cluster->next[order] = offset; 885 return found; 886 } ··· 922 si->lowest_bit = si->max; 923 si->highest_bit = 0; 924 del_from_avail_list(si); 925 + 926 + if (vm_swap_full()) 927 + schedule_work(&si->reclaim_work); 928 } 929 } 930 ··· 2816 wait_for_completion(&p->comp); 2817 2818 flush_work(&p->discard_work); 2819 + flush_work(&p->reclaim_work); 2820 2821 destroy_swap_extents(p); 2822 if (p->flags & SWP_CONTINUED) ··· 3376 return PTR_ERR(si); 3377 3378 INIT_WORK(&si->discard_work, swap_discard_work); 3379 + INIT_WORK(&si->reclaim_work, swap_reclaim_work); 3380 3381 name = getname(specialfile); 3382 if (IS_ERR(name)) {
+54 -48
mm/vmscan.c
··· 56 #include <linux/khugepaged.h> 57 #include <linux/rculist_nulls.h> 58 #include <linux/random.h> 59 60 #include <asm/tlbflush.h> 61 #include <asm/div64.h> ··· 3295 return false; 3296 } 3297 3298 - static unsigned long get_pte_pfn(pte_t pte, struct vm_area_struct *vma, unsigned long addr) 3299 { 3300 unsigned long pfn = pte_pfn(pte); 3301 ··· 3308 if (WARN_ON_ONCE(pte_devmap(pte) || pte_special(pte))) 3309 return -1; 3310 3311 if (WARN_ON_ONCE(!pfn_valid(pfn))) 3312 return -1; 3313 3314 return pfn; 3315 } 3316 3317 - static unsigned long get_pmd_pfn(pmd_t pmd, struct vm_area_struct *vma, unsigned long addr) 3318 { 3319 unsigned long pfn = pmd_pfn(pmd); 3320 ··· 3333 if (WARN_ON_ONCE(pmd_devmap(pmd))) 3334 return -1; 3335 3336 if (WARN_ON_ONCE(!pfn_valid(pfn))) 3337 return -1; 3338 3339 return pfn; ··· 3349 struct pglist_data *pgdat, bool can_swap) 3350 { 3351 struct folio *folio; 3352 - 3353 - /* try to avoid unnecessary memory loads */ 3354 - if (pfn < pgdat->node_start_pfn || pfn >= pgdat_end_pfn(pgdat)) 3355 - return NULL; 3356 3357 folio = pfn_folio(pfn); 3358 if (folio_nid(folio) != pgdat->node_id) ··· 3405 total++; 3406 walk->mm_stats[MM_LEAF_TOTAL]++; 3407 3408 - pfn = get_pte_pfn(ptent, args->vma, addr); 3409 if (pfn == -1) 3410 continue; 3411 - 3412 - if (!pte_young(ptent)) { 3413 - walk->mm_stats[MM_LEAF_OLD]++; 3414 - continue; 3415 - } 3416 3417 folio = get_pfn_folio(pfn, memcg, pgdat, walk->can_swap); 3418 if (!folio) 3419 continue; 3420 3421 - if (!ptep_test_and_clear_young(args->vma, addr, pte + i)) 3422 - VM_WARN_ON_ONCE(true); 3423 3424 young++; 3425 walk->mm_stats[MM_LEAF_YOUNG]++; ··· 3480 /* don't round down the first address */ 3481 addr = i ? (*first & PMD_MASK) + i * PMD_SIZE : *first; 3482 3483 - pfn = get_pmd_pfn(pmd[i], vma, addr); 3484 - if (pfn == -1) 3485 goto next; 3486 3487 if (!pmd_trans_huge(pmd[i])) { 3488 - if (!walk->force_scan && should_clear_pmd_young()) 3489 pmdp_test_and_clear_young(vma, addr, pmd + i); 3490 goto next; 3491 } 3492 3493 folio = get_pfn_folio(pfn, memcg, pgdat, walk->can_swap); 3494 if (!folio) 3495 goto next; 3496 3497 - if (!pmdp_test_and_clear_young(vma, addr, pmd + i)) 3498 goto next; 3499 3500 walk->mm_stats[MM_LEAF_YOUNG]++; ··· 3556 } 3557 3558 if (pmd_trans_huge(val)) { 3559 - unsigned long pfn = pmd_pfn(val); 3560 struct pglist_data *pgdat = lruvec_pgdat(walk->lruvec); 3561 3562 walk->mm_stats[MM_LEAF_TOTAL]++; 3563 3564 - if (!pmd_young(val)) { 3565 - walk->mm_stats[MM_LEAF_OLD]++; 3566 - continue; 3567 - } 3568 - 3569 - /* try to avoid unnecessary memory loads */ 3570 - if (pfn < pgdat->node_start_pfn || pfn >= pgdat_end_pfn(pgdat)) 3571 - continue; 3572 - 3573 - walk_pmd_range_locked(pud, addr, vma, args, bitmap, &first); 3574 continue; 3575 } 3576 3577 - walk->mm_stats[MM_NONLEAF_TOTAL]++; 3578 - 3579 - if (!walk->force_scan && should_clear_pmd_young()) { 3580 if (!pmd_young(val)) 3581 continue; 3582 ··· 4041 * the PTE table to the Bloom filter. This forms a feedback loop between the 4042 * eviction and the aging. 4043 */ 4044 - void lru_gen_look_around(struct page_vma_mapped_walk *pvmw) 4045 { 4046 int i; 4047 unsigned long start; 4048 unsigned long end; 4049 struct lru_gen_mm_walk *walk; 4050 - int young = 0; 4051 pte_t *pte = pvmw->pte; 4052 unsigned long addr = pvmw->address; 4053 struct vm_area_struct *vma = pvmw->vma; ··· 4063 lockdep_assert_held(pvmw->ptl); 4064 VM_WARN_ON_ONCE_FOLIO(folio_test_lru(folio), folio); 4065 4066 if (spin_is_contended(pvmw->ptl)) 4067 - return; 4068 4069 /* exclude special VMAs containing anon pages from COW */ 4070 if (vma->vm_flags & VM_SPECIAL) 4071 - return; 4072 4073 /* avoid taking the LRU lock under the PTL when possible */ 4074 walk = current->reclaim_state ? current->reclaim_state->mm_walk : NULL; 4075 4076 start = max(addr & PMD_MASK, vma->vm_start); 4077 end = min(addr | ~PMD_MASK, vma->vm_end - 1) + 1; 4078 4079 if (end - start > MIN_LRU_BATCH * PAGE_SIZE) { 4080 if (addr - start < MIN_LRU_BATCH * PAGE_SIZE / 2) ··· 4095 4096 /* folio_update_gen() requires stable folio_memcg() */ 4097 if (!mem_cgroup_trylock_pages(memcg)) 4098 - return; 4099 4100 arch_enter_lazy_mmu_mode(); 4101 ··· 4105 unsigned long pfn; 4106 pte_t ptent = ptep_get(pte + i); 4107 4108 - pfn = get_pte_pfn(ptent, vma, addr); 4109 if (pfn == -1) 4110 - continue; 4111 - 4112 - if (!pte_young(ptent)) 4113 continue; 4114 4115 folio = get_pfn_folio(pfn, memcg, pgdat, can_swap); 4116 if (!folio) 4117 continue; 4118 4119 - if (!ptep_test_and_clear_young(vma, addr, pte + i)) 4120 - VM_WARN_ON_ONCE(true); 4121 4122 young++; 4123 ··· 4144 /* feedback from rmap walkers to page table walkers */ 4145 if (mm_state && suitable_to_scan(i, young)) 4146 update_bloom_filter(mm_state, max_seq, pvmw->pmd); 4147 } 4148 4149 /****************************************************************************** ··· 5260 for (tier = 0; tier < MAX_NR_TIERS; tier++) { 5261 seq_printf(m, " %10d", tier); 5262 for (type = 0; type < ANON_AND_FILE; type++) { 5263 - const char *s = " "; 5264 unsigned long n[3] = {}; 5265 5266 if (seq == max_seq) { 5267 - s = "RT "; 5268 n[0] = READ_ONCE(lrugen->avg_refaulted[type][tier]); 5269 n[1] = READ_ONCE(lrugen->avg_total[type][tier]); 5270 } else if (seq == min_seq[type] || NR_HIST_GENS > 1) { ··· 5286 5287 seq_puts(m, " "); 5288 for (i = 0; i < NR_MM_STATS; i++) { 5289 - const char *s = " "; 5290 unsigned long n = 0; 5291 5292 if (seq == max_seq && NR_HIST_GENS == 1) { 5293 - s = "LOYNFA"; 5294 n = READ_ONCE(mm_state->stats[hist][i]); 5295 } else if (seq != max_seq && NR_HIST_GENS > 1) { 5296 - s = "loynfa"; 5297 n = READ_ONCE(mm_state->stats[hist][i]); 5298 } 5299
··· 56 #include <linux/khugepaged.h> 57 #include <linux/rculist_nulls.h> 58 #include <linux/random.h> 59 + #include <linux/mmu_notifier.h> 60 61 #include <asm/tlbflush.h> 62 #include <asm/div64.h> ··· 3294 return false; 3295 } 3296 3297 + static unsigned long get_pte_pfn(pte_t pte, struct vm_area_struct *vma, unsigned long addr, 3298 + struct pglist_data *pgdat) 3299 { 3300 unsigned long pfn = pte_pfn(pte); 3301 ··· 3306 if (WARN_ON_ONCE(pte_devmap(pte) || pte_special(pte))) 3307 return -1; 3308 3309 + if (!pte_young(pte) && !mm_has_notifiers(vma->vm_mm)) 3310 + return -1; 3311 + 3312 if (WARN_ON_ONCE(!pfn_valid(pfn))) 3313 + return -1; 3314 + 3315 + if (pfn < pgdat->node_start_pfn || pfn >= pgdat_end_pfn(pgdat)) 3316 return -1; 3317 3318 return pfn; 3319 } 3320 3321 + static unsigned long get_pmd_pfn(pmd_t pmd, struct vm_area_struct *vma, unsigned long addr, 3322 + struct pglist_data *pgdat) 3323 { 3324 unsigned long pfn = pmd_pfn(pmd); 3325 ··· 3324 if (WARN_ON_ONCE(pmd_devmap(pmd))) 3325 return -1; 3326 3327 + if (!pmd_young(pmd) && !mm_has_notifiers(vma->vm_mm)) 3328 + return -1; 3329 + 3330 if (WARN_ON_ONCE(!pfn_valid(pfn))) 3331 + return -1; 3332 + 3333 + if (pfn < pgdat->node_start_pfn || pfn >= pgdat_end_pfn(pgdat)) 3334 return -1; 3335 3336 return pfn; ··· 3334 struct pglist_data *pgdat, bool can_swap) 3335 { 3336 struct folio *folio; 3337 3338 folio = pfn_folio(pfn); 3339 if (folio_nid(folio) != pgdat->node_id) ··· 3394 total++; 3395 walk->mm_stats[MM_LEAF_TOTAL]++; 3396 3397 + pfn = get_pte_pfn(ptent, args->vma, addr, pgdat); 3398 if (pfn == -1) 3399 continue; 3400 3401 folio = get_pfn_folio(pfn, memcg, pgdat, walk->can_swap); 3402 if (!folio) 3403 continue; 3404 3405 + if (!ptep_clear_young_notify(args->vma, addr, pte + i)) 3406 + continue; 3407 3408 young++; 3409 walk->mm_stats[MM_LEAF_YOUNG]++; ··· 3474 /* don't round down the first address */ 3475 addr = i ? (*first & PMD_MASK) + i * PMD_SIZE : *first; 3476 3477 + if (!pmd_present(pmd[i])) 3478 goto next; 3479 3480 if (!pmd_trans_huge(pmd[i])) { 3481 + if (!walk->force_scan && should_clear_pmd_young() && 3482 + !mm_has_notifiers(args->mm)) 3483 pmdp_test_and_clear_young(vma, addr, pmd + i); 3484 goto next; 3485 } 3486 + 3487 + pfn = get_pmd_pfn(pmd[i], vma, addr, pgdat); 3488 + if (pfn == -1) 3489 + goto next; 3490 3491 folio = get_pfn_folio(pfn, memcg, pgdat, walk->can_swap); 3492 if (!folio) 3493 goto next; 3494 3495 + if (!pmdp_clear_young_notify(vma, addr, pmd + i)) 3496 goto next; 3497 3498 walk->mm_stats[MM_LEAF_YOUNG]++; ··· 3546 } 3547 3548 if (pmd_trans_huge(val)) { 3549 struct pglist_data *pgdat = lruvec_pgdat(walk->lruvec); 3550 + unsigned long pfn = get_pmd_pfn(val, vma, addr, pgdat); 3551 3552 walk->mm_stats[MM_LEAF_TOTAL]++; 3553 3554 + if (pfn != -1) 3555 + walk_pmd_range_locked(pud, addr, vma, args, bitmap, &first); 3556 continue; 3557 } 3558 3559 + if (!walk->force_scan && should_clear_pmd_young() && 3560 + !mm_has_notifiers(args->mm)) { 3561 if (!pmd_young(val)) 3562 continue; 3563 ··· 4040 * the PTE table to the Bloom filter. This forms a feedback loop between the 4041 * eviction and the aging. 4042 */ 4043 + bool lru_gen_look_around(struct page_vma_mapped_walk *pvmw) 4044 { 4045 int i; 4046 unsigned long start; 4047 unsigned long end; 4048 struct lru_gen_mm_walk *walk; 4049 + int young = 1; 4050 pte_t *pte = pvmw->pte; 4051 unsigned long addr = pvmw->address; 4052 struct vm_area_struct *vma = pvmw->vma; ··· 4062 lockdep_assert_held(pvmw->ptl); 4063 VM_WARN_ON_ONCE_FOLIO(folio_test_lru(folio), folio); 4064 4065 + if (!ptep_clear_young_notify(vma, addr, pte)) 4066 + return false; 4067 + 4068 if (spin_is_contended(pvmw->ptl)) 4069 + return true; 4070 4071 /* exclude special VMAs containing anon pages from COW */ 4072 if (vma->vm_flags & VM_SPECIAL) 4073 + return true; 4074 4075 /* avoid taking the LRU lock under the PTL when possible */ 4076 walk = current->reclaim_state ? current->reclaim_state->mm_walk : NULL; 4077 4078 start = max(addr & PMD_MASK, vma->vm_start); 4079 end = min(addr | ~PMD_MASK, vma->vm_end - 1) + 1; 4080 + 4081 + if (end - start == PAGE_SIZE) 4082 + return true; 4083 4084 if (end - start > MIN_LRU_BATCH * PAGE_SIZE) { 4085 if (addr - start < MIN_LRU_BATCH * PAGE_SIZE / 2) ··· 4088 4089 /* folio_update_gen() requires stable folio_memcg() */ 4090 if (!mem_cgroup_trylock_pages(memcg)) 4091 + return true; 4092 4093 arch_enter_lazy_mmu_mode(); 4094 ··· 4098 unsigned long pfn; 4099 pte_t ptent = ptep_get(pte + i); 4100 4101 + pfn = get_pte_pfn(ptent, vma, addr, pgdat); 4102 if (pfn == -1) 4103 continue; 4104 4105 folio = get_pfn_folio(pfn, memcg, pgdat, can_swap); 4106 if (!folio) 4107 continue; 4108 4109 + if (!ptep_clear_young_notify(vma, addr, pte + i)) 4110 + continue; 4111 4112 young++; 4113 ··· 4140 /* feedback from rmap walkers to page table walkers */ 4141 if (mm_state && suitable_to_scan(i, young)) 4142 update_bloom_filter(mm_state, max_seq, pvmw->pmd); 4143 + 4144 + return true; 4145 } 4146 4147 /****************************************************************************** ··· 5254 for (tier = 0; tier < MAX_NR_TIERS; tier++) { 5255 seq_printf(m, " %10d", tier); 5256 for (type = 0; type < ANON_AND_FILE; type++) { 5257 + const char *s = "xxx"; 5258 unsigned long n[3] = {}; 5259 5260 if (seq == max_seq) { 5261 + s = "RTx"; 5262 n[0] = READ_ONCE(lrugen->avg_refaulted[type][tier]); 5263 n[1] = READ_ONCE(lrugen->avg_total[type][tier]); 5264 } else if (seq == min_seq[type] || NR_HIST_GENS > 1) { ··· 5280 5281 seq_puts(m, " "); 5282 for (i = 0; i < NR_MM_STATS; i++) { 5283 + const char *s = "xxxx"; 5284 unsigned long n = 0; 5285 5286 if (seq == max_seq && NR_HIST_GENS == 1) { 5287 + s = "TYFA"; 5288 n = READ_ONCE(mm_state->stats[hist][i]); 5289 } else if (seq != max_seq && NR_HIST_GENS > 1) { 5290 + s = "tyfa"; 5291 n = READ_ONCE(mm_state->stats[hist][i]); 5292 } 5293
+5 -4
tools/mm/page-types.c
··· 22 #include <time.h> 23 #include <setjmp.h> 24 #include <signal.h> 25 #include <sys/types.h> 26 #include <sys/errno.h> 27 #include <sys/fcntl.h> ··· 392 if (opt_file) 393 printf("%lx\t", voff); 394 if (opt_list_cgroup) 395 - printf("@%llu\t", (unsigned long long)cgroup0); 396 if (opt_list_mapcnt) 397 - printf("%lu\t", mapcnt0); 398 printf("%lx\t%lx\t%s\n", 399 index, count, page_flag_name(flags0)); 400 } ··· 420 if (opt_file) 421 printf("%lx\t", voffset); 422 if (opt_list_cgroup) 423 - printf("@%llu\t", (unsigned long long)cgroup); 424 if (opt_list_mapcnt) 425 - printf("%lu\t", mapcnt); 426 427 printf("%lx\t%s\n", offset, page_flag_name(flags)); 428 }
··· 22 #include <time.h> 23 #include <setjmp.h> 24 #include <signal.h> 25 + #include <inttypes.h> 26 #include <sys/types.h> 27 #include <sys/errno.h> 28 #include <sys/fcntl.h> ··· 391 if (opt_file) 392 printf("%lx\t", voff); 393 if (opt_list_cgroup) 394 + printf("@%" PRIu64 "\t", cgroup0); 395 if (opt_list_mapcnt) 396 + printf("%" PRIu64 "\t", mapcnt0); 397 printf("%lx\t%lx\t%s\n", 398 index, count, page_flag_name(flags0)); 399 } ··· 419 if (opt_file) 420 printf("%lx\t", voffset); 421 if (opt_list_cgroup) 422 + printf("@%" PRIu64 "\t", cgroup) 423 if (opt_list_mapcnt) 424 + printf("%" PRIu64 "\t", mapcnt); 425 426 printf("%lx\t%s\n", offset, page_flag_name(flags)); 427 }
+3 -1
tools/mm/slabinfo.c
··· 1297 slab->cpu_partial_free = get_obj("cpu_partial_free"); 1298 slab->alloc_node_mismatch = get_obj("alloc_node_mismatch"); 1299 slab->deactivate_bypass = get_obj("deactivate_bypass"); 1300 - chdir(".."); 1301 if (slab->name[0] == ':') 1302 alias_targets++; 1303 slab++;
··· 1297 slab->cpu_partial_free = get_obj("cpu_partial_free"); 1298 slab->alloc_node_mismatch = get_obj("alloc_node_mismatch"); 1299 slab->deactivate_bypass = get_obj("deactivate_bypass"); 1300 + if (chdir("..")) 1301 + fatal("Unable to chdir from slab ../%s\n", 1302 + slab->name); 1303 if (slab->name[0] == ':') 1304 alias_targets++; 1305 slab++;