History

mm: switch deferred split shrinker to list_lru

The deferred split queue handles cgroups in a suboptimal fashion. The queue is per-NUMA node or per-cgroup, not the intersection. That means on a cgrouped system, a node-restricted allocation entering reclaim can end up splitting large pages on other nodes: alloc/unmap deferred_split_folio() list_add_tail(memcg->split_queue) set_shrinker_bit(memcg, node, deferred_shrinker_id) for_each_zone_zonelist_nodemask(restricted_nodes) mem_cgroup_iter() shrink_slab(node, memcg) shrink_slab_memcg(node, memcg) if test_shrinker_bit(memcg, node, deferred_shrinker_id) deferred_split_scan() walks memcg->split_queue The shrinker bit adds an imperfect guard rail. As soon as the cgroup has a single large page on the node of interest, all large pages owned by that memcg, including those on other nodes, will be split. list_lru properly sets up per-node, per-cgroup lists. As a bonus, it streamlines a lot of the list operations and reclaim walks. It's used widely by other major shrinkers already. Convert the deferred split queue as well. The list_lru per-memcg heads are instantiated on demand when the first object of interest is allocated for a cgroup, by calling folio_memcg_alloc_deferred(). Add calls to where splittable pages are created: anon faults, swapin faults, khugepaged collapse. These calls create all possible node heads for the cgroup at once, so the migration code (between nodes) doesn't need any special care. [akpm@linux-foundation.org: fix build with CONFIG_TRANSPARENT_HUGEPAGE=n] Link: https://lore.kernel.org/202605281620.lc3rtkBm-lkp@intel.com [hannes@cmpxchg.org: fix cgroup.memory=nokmem handling] Link: https://lore.kernel.org/ah9PGv12mqai84ES@cmpxchg.org Link: https://lore.kernel.org/20260527204757.2544958-10-hannes@cmpxchg.org Signed-off-by: Johannes Weiner <hannes@cmpxchg.org> Reported-by: Mikhail Zaslonko <zaslonko@linux.ibm.com> Tested-by: Mikhail Zaslonko <zaslonko@linux.ibm.com> Acked-by: Shakeel Butt <shakeel.butt@linux.dev> Reviewed-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org> Acked-by: Usama Arif <usama.arif@linux.dev> Reviewed-by: Kairui Song <kasong@tencent.com> Cc: Baolin Wang <baolin.wang@linux.alibaba.com> Cc: Barry Song <baohua@kernel.org> Cc: Dave Chinner <david@fromorbit.com> Cc: David Hildenbrand (Arm) <david@kernel.org> Cc: Dev Jain <dev.jain@arm.com> Cc: Lance Yang <lance.yang@linux.dev> Cc: Liam R. Howlett <liam@infradead.org> Cc: Michal Hocko <mhocko@kernel.org> Cc: Muchun Song <muchun.song@linux.dev> Cc: Nico Pache <npache@redhat.com> Cc: Roman Gushchin <roman.gushchin@linux.dev> Cc: Ryan Roberts <ryan.roberts@arm.com> Cc: Vasily Gorbik <gor@linux.ibm.com> Cc: Vlastimil Babka <vbabka@kernel.org> Cc: Zi Yan <ziy@nvidia.com> Cc: kernel test robot <lkp@intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

Johannes Weiner committed 5 months ago

Commit fafaece1 parent 65180e910 files · +160 −288Browse files

Unified · Split

10 files
  1. include/linux/huge_mm.h +12 −5
  2. include/linux/memcontrol.h +0 −4
  3. include/linux/mmzone.h +0 −12
  4. mm/huge_memory.c +125 −242
  5. mm/internal.h +1 −1
  6. mm/khugepaged.c +5 −0
  7. mm/memcontrol.c +3 −9
  8. mm/memory.c +4 −0
  9. mm/mm_init.c +0 −15
  10. mm/swap_state.c +10 −0
include/linux/huge_mm.h+12−5
@@ -439,10 +439,10 @@ static inline int split_huge_page(struct page *page) · 438 unmodified lines
439{439{
440 return split_huge_page_to_list_to_order(page, NULL, 0);440 return split_huge_page_to_list_to_order(page, NULL, 0);
441}441}
442
443int folio_memcg_alloc_deferred(struct folio *folio);
444
442void deferred_split_folio(struct folio *folio, bool partially_mapped);445void deferred_split_folio(struct folio *folio, bool partially_mapped);
443#ifdef CONFIG_MEMCG
444void reparent_deferred_split_queue(struct mem_cgroup *memcg);
445#endif
446 446
447void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,447void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
448 unsigned long address, bool freeze);448 unsigned long address, bool freeze);
@@ -679,8 +679,15 @@ static inline int try_folio_split_to_order(struct folio *folio, · 230 unmodified lines
679 return -EINVAL;679 return -EINVAL;
680}680}
681 681
682static inline void deferred_split_folio(struct folio *folio, bool partially_mapped) {}682static inline int folio_memcg_alloc_deferred(struct folio *folio)
683static inline void reparent_deferred_split_queue(struct mem_cgroup *memcg) {}683{
684 return 0;
685}
686
687static inline void deferred_split_folio(struct folio *folio, bool partially_mapped)
688{
689}
690
684#define split_huge_pmd(__vma, __pmd, __address) \691#define split_huge_pmd(__vma, __pmd, __address) \
685 do { } while (0)692 do { } while (0)
686 693
include/linux/memcontrol.h+0−4
@@ -278,10 +278,6 @@ struct mem_cgroup { · 277 unmodified lines
278 struct memcg_cgwb_frn cgwb_frn[MEMCG_CGWB_FRN_CNT];278 struct memcg_cgwb_frn cgwb_frn[MEMCG_CGWB_FRN_CNT];
279#endif279#endif
280 280
281#ifdef CONFIG_TRANSPARENT_HUGEPAGE
282 struct deferred_split deferred_split_queue;
283#endif
284
285#ifdef CONFIG_LRU_GEN_WALKS_MMU281#ifdef CONFIG_LRU_GEN_WALKS_MMU
286 /* per-memcg mm_struct list */282 /* per-memcg mm_struct list */
287 struct lru_gen_mm_list mm_list;283 struct lru_gen_mm_list mm_list;
include/linux/mmzone.h+0−12
@@ -1431,14 +1431,6 @@ struct zonelist { · 1430 unmodified lines
1431 */1431 */
1432extern struct page *mem_map;1432extern struct page *mem_map;
1433 1433
1434#ifdef CONFIG_TRANSPARENT_HUGEPAGE
1435struct deferred_split {
1436 spinlock_t split_queue_lock;
1437 struct list_head split_queue;
1438 unsigned long split_queue_len;
1439};
1440#endif
1441
1442#ifdef CONFIG_MEMORY_FAILURE1434#ifdef CONFIG_MEMORY_FAILURE
1443/*1435/*
1444 * Per NUMA node memory failure handling statistics.1436 * Per NUMA node memory failure handling statistics.
@@ -1564,10 +1556,6 @@ typedef struct pglist_data { · 119 unmodified lines
1564 unsigned long first_deferred_pfn;1556 unsigned long first_deferred_pfn;
1565#endif /* CONFIG_DEFERRED_STRUCT_PAGE_INIT */1557#endif /* CONFIG_DEFERRED_STRUCT_PAGE_INIT */
1566 1558
1567#ifdef CONFIG_TRANSPARENT_HUGEPAGE
1568 struct deferred_split deferred_split_queue;
1569#endif
1570
1571#ifdef CONFIG_NUMA_BALANCING1559#ifdef CONFIG_NUMA_BALANCING
1572 /* start time in ms of current promote rate limit period */1560 /* start time in ms of current promote rate limit period */
1573 unsigned int nbp_rl_start;1561 unsigned int nbp_rl_start;
mm/huge_memory.c+125−242
@@ -14,6 +14,7 @@ · 13 unmodified lines
14#include <linux/mmu_notifier.h>14#include <linux/mmu_notifier.h>
15#include <linux/rmap.h>15#include <linux/rmap.h>
16#include <linux/swap.h>16#include <linux/swap.h>
17#include <linux/list_lru.h>
17#include <linux/shrinker.h>18#include <linux/shrinker.h>
18#include <linux/mm_inline.h>19#include <linux/mm_inline.h>
19#include <linux/swapops.h>20#include <linux/swapops.h>
@@ -67,6 +68,8 @@ unsigned long transparent_hugepage_flags __read_mostly = · 47 unmodified lines
67 (1<<TRANSPARENT_HUGEPAGE_DEFRAG_KHUGEPAGED_FLAG)|68 (1<<TRANSPARENT_HUGEPAGE_DEFRAG_KHUGEPAGED_FLAG)|
68 (1<<TRANSPARENT_HUGEPAGE_USE_ZERO_PAGE_FLAG);69 (1<<TRANSPARENT_HUGEPAGE_USE_ZERO_PAGE_FLAG);
69 70
71static struct lock_class_key deferred_split_key;
72static struct list_lru deferred_split_lru;
70static struct shrinker *deferred_split_shrinker;73static struct shrinker *deferred_split_shrinker;
71static unsigned long deferred_split_count(struct shrinker *shrink,74static unsigned long deferred_split_count(struct shrinker *shrink,
72 struct shrink_control *sc);75 struct shrink_control *sc);
@@ -932,15 +935,28 @@ static inline void hugepage_exit_sysfs(struct kobject *hugepage_kobj) · 859 unmodified lines
932}935}
933#endif /* CONFIG_SYSFS */936#endif /* CONFIG_SYSFS */
934 937
938int folio_memcg_alloc_deferred(struct folio *folio)
939{
940 if (mem_cgroup_disabled())
941 return 0;
942 return folio_memcg_list_lru_alloc(folio, &deferred_split_lru, GFP_KERNEL);
943}
944
935static int __init thp_shrinker_init(void)945static int __init thp_shrinker_init(void)
936{946{
937 deferred_split_shrinker = shrinker_alloc(SHRINKER_NUMA_AWARE |947 deferred_split_shrinker = shrinker_alloc(SHRINKER_NUMA_AWARE |
938 SHRINKER_MEMCG_AWARE |948 SHRINKER_MEMCG_AWARE,
939 SHRINKER_NONSLAB,
940 "thp-deferred_split");949 "thp-deferred_split");
941 if (!deferred_split_shrinker)950 if (!deferred_split_shrinker)
942 return -ENOMEM;951 return -ENOMEM;
943 952
953 if (list_lru_init_memcg_key(&deferred_split_lru,
954 deferred_split_shrinker,
955 &deferred_split_key)) {
956 shrinker_free(deferred_split_shrinker);
957 return -ENOMEM;
958 }
959
944 deferred_split_shrinker->count_objects = deferred_split_count;960 deferred_split_shrinker->count_objects = deferred_split_count;
945 deferred_split_shrinker->scan_objects = deferred_split_scan;961 deferred_split_shrinker->scan_objects = deferred_split_scan;
946 shrinker_register(deferred_split_shrinker);962 shrinker_register(deferred_split_shrinker);
@@ -962,6 +978,7 @@ static int __init thp_shrinker_init(void) · 15 unmodified lines
962 huge_zero_folio_shrinker = shrinker_alloc(0, "thp-zero");978 huge_zero_folio_shrinker = shrinker_alloc(0, "thp-zero");
963 if (!huge_zero_folio_shrinker) {979 if (!huge_zero_folio_shrinker) {
964 shrinker_free(deferred_split_shrinker);980 shrinker_free(deferred_split_shrinker);
981 list_lru_destroy(&deferred_split_lru);
965 return -ENOMEM;982 return -ENOMEM;
966 }983 }
967 984
@@ -976,6 +993,7 @@ static void __init thp_shrinker_exit(void) · 8 unmodified lines
976{993{
977 shrinker_free(huge_zero_folio_shrinker);994 shrinker_free(huge_zero_folio_shrinker);
978 shrinker_free(deferred_split_shrinker);995 shrinker_free(deferred_split_shrinker);
996 list_lru_destroy(&deferred_split_lru);
979}997}
980 998
981static int __init hugepage_init(void)999static int __init hugepage_init(void)
@@ -1155,119 +1173,6 @@ pmd_t maybe_pmd_mkwrite(pmd_t pmd, struct vm_area_struct *vma) · 173 unmodified lines
1155 return pmd;1173 return pmd;
1156}1174}
1157 1175
1158static struct deferred_split *split_queue_node(int nid)
1159{
1160 struct pglist_data *pgdata = NODE_DATA(nid);
1161
1162 return &pgdata->deferred_split_queue;
1163}
1164
1165#ifdef CONFIG_MEMCG
1166static inline
1167struct mem_cgroup *folio_split_queue_memcg(struct folio *folio,
1168 struct deferred_split *queue)
1169{
1170 if (mem_cgroup_disabled())
1171 return NULL;
1172 if (split_queue_node(folio_nid(folio)) == queue)
1173 return NULL;
1174 return container_of(queue, struct mem_cgroup, deferred_split_queue);
1175}
1176
1177static struct deferred_split *memcg_split_queue(int nid, struct mem_cgroup *memcg)
1178{
1179 return memcg ? &memcg->deferred_split_queue : split_queue_node(nid);
1180}
1181#else
1182static inline
1183struct mem_cgroup *folio_split_queue_memcg(struct folio *folio,
1184 struct deferred_split *queue)
1185{
1186 return NULL;
1187}
1188
1189static struct deferred_split *memcg_split_queue(int nid, struct mem_cgroup *memcg)
1190{
1191 return split_queue_node(nid);
1192}
1193#endif
1194
1195static struct deferred_split *split_queue_lock(int nid, struct mem_cgroup *memcg)
1196{
1197 struct deferred_split *queue;
1198
1199retry:
1200 queue = memcg_split_queue(nid, memcg);
1201 spin_lock(&queue->split_queue_lock);
1202 /*
1203 * There is a period between setting memcg to dying and reparenting
1204 * deferred split queue, and during this period the THPs in the deferred
1205 * split queue will be hidden from the shrinker side.
1206 */
1207 if (unlikely(memcg_is_dying(memcg))) {
1208 spin_unlock(&queue->split_queue_lock);
1209 memcg = parent_mem_cgroup(memcg);
1210 goto retry;
1211 }
1212
1213 return queue;
1214}
1215
1216static struct deferred_split *
1217split_queue_lock_irqsave(int nid, struct mem_cgroup *memcg, unsigned long *flags)
1218{
1219 struct deferred_split *queue;
1220
1221retry:
1222 queue = memcg_split_queue(nid, memcg);
1223 spin_lock_irqsave(&queue->split_queue_lock, *flags);
1224 if (unlikely(memcg_is_dying(memcg))) {
1225 spin_unlock_irqrestore(&queue->split_queue_lock, *flags);
1226 memcg = parent_mem_cgroup(memcg);
1227 goto retry;
1228 }
1229
1230 return queue;
1231}
1232
1233static struct deferred_split *folio_split_queue_lock(struct folio *folio)
1234{
1235 struct deferred_split *queue;
1236
1237 rcu_read_lock();
1238 queue = split_queue_lock(folio_nid(folio), folio_memcg(folio));
1239 /*
1240 * The memcg destruction path is acquiring the split queue lock for
1241 * reparenting. Once you have it locked, it's safe to drop the rcu lock.
1242 */
1243 rcu_read_unlock();
1244
1245 return queue;
1246}
1247
1248static struct deferred_split *
1249folio_split_queue_lock_irqsave(struct folio *folio, unsigned long *flags)
1250{
1251 struct deferred_split *queue;
1252
1253 rcu_read_lock();
1254 queue = split_queue_lock_irqsave(folio_nid(folio), folio_memcg(folio), flags);
1255 rcu_read_unlock();
1256
1257 return queue;
1258}
1259
1260static inline void split_queue_unlock(struct deferred_split *queue)
1261{
1262 spin_unlock(&queue->split_queue_lock);
1263}
1264
1265static inline void split_queue_unlock_irqrestore(struct deferred_split *queue,
1266 unsigned long flags)
1267{
1268 spin_unlock_irqrestore(&queue->split_queue_lock, flags);
1269}
1270
1271static inline bool is_transparent_hugepage(const struct folio *folio)1176static inline bool is_transparent_hugepage(const struct folio *folio)
1272{1177{
1273 if (!folio_test_large(folio))1178 if (!folio_test_large(folio))
@@ -1368,6 +1273,14 @@ static struct folio *vma_alloc_anon_folio_pmd(struct vm_area_struct *vma, · 94 unmodified lines
1368 count_mthp_stat(order, MTHP_STAT_ANON_FAULT_FALLBACK_CHARGE);1273 count_mthp_stat(order, MTHP_STAT_ANON_FAULT_FALLBACK_CHARGE);
1369 return NULL;1274 return NULL;
1370 }1275 }
1276
1277 if (folio_memcg_alloc_deferred(folio)) {
1278 folio_put(folio);
1279 count_vm_event(THP_FAULT_FALLBACK);
1280 count_mthp_stat(order, MTHP_STAT_ANON_FAULT_FALLBACK);
1281 return NULL;
1282 }
1283
1371 folio_throttle_swaprate(folio, gfp);1284 folio_throttle_swaprate(folio, gfp);
1372 1285
1373 /*1286 /*
@@ -3903,34 +3816,43 @@ static int __folio_freeze_and_split_unmapped(struct folio *folio, unsigned int n · 2529 unmodified lines
3903 struct folio *end_folio = folio_next(folio);3816 struct folio *end_folio = folio_next(folio);
3904 struct folio *new_folio, *next;3817 struct folio *new_folio, *next;
3905 int old_order = folio_order(folio);3818 int old_order = folio_order(folio);
3819 struct list_lru_one *lru;
3820 bool dequeue_deferred;
3906 int ret = 0;3821 int ret = 0;
3907 struct deferred_split *ds_queue;
3908 3822
3909 VM_WARN_ON_ONCE(!mapping && end);3823 VM_WARN_ON_ONCE(!mapping && end);
3910 /* Prevent deferred_split_scan() touching ->_refcount */3824 /*
3911 ds_queue = folio_split_queue_lock(folio);3825 * If this folio can be on the deferred split queue, lock out
3826 * the shrinker before freezing the ref. If the shrinker sees
3827 * a 0-ref folio, it assumes it beat folio_put() to the list
3828 * lock and must clean up the LRU state - the same dequeue we
3829 * will do below as part of the split.
3830 */
3831 dequeue_deferred = folio_test_anon(folio) && old_order > 1;
3832 if (dequeue_deferred) {
3833 struct mem_cgroup *memcg;
3834
3835 rcu_read_lock();
3836 memcg = folio_memcg(folio);
3837 lru = list_lru_lock(&deferred_split_lru,
3838 folio_nid(folio), &memcg);
3839 }
3912 if (folio_ref_freeze(folio, folio_cache_ref_count(folio) + 1)) {3840 if (folio_ref_freeze(folio, folio_cache_ref_count(folio) + 1)) {
3913 struct swap_cluster_info *ci = NULL;3841 struct swap_cluster_info *ci = NULL;
3914 struct lruvec *lruvec;3842 struct lruvec *lruvec;
3915 3843
3916 if (old_order > 1) {3844 if (dequeue_deferred) {
3917 if (!list_empty(&folio->_deferred_list)) {3845 __list_lru_del(&deferred_split_lru, lru,
3918 ds_queue->split_queue_len--;3846 &folio->_deferred_list, folio_nid(folio));
3919 /*
3920 * Reinitialize page_deferred_list after removing the
3921 * page from the split_queue, otherwise a subsequent
3922 * split will see list corruption when checking the
3923 * page_deferred_list.
3924 */
3925 list_del_init(&folio->_deferred_list);
3926 }
3927 if (folio_test_partially_mapped(folio)) {3847 if (folio_test_partially_mapped(folio)) {
3928 folio_clear_partially_mapped(folio);3848 folio_clear_partially_mapped(folio);
3929 mod_mthp_stat(old_order,3849 mod_mthp_stat(old_order,
3930 MTHP_STAT_NR_ANON_PARTIALLY_MAPPED, -1);3850 MTHP_STAT_NR_ANON_PARTIALLY_MAPPED, -1);
3931 }3851 }
3852 list_lru_unlock(lru);
3853 rcu_read_unlock();
3932 }3854 }
3933 split_queue_unlock(ds_queue);3855
3934 if (mapping) {3856 if (mapping) {
3935 int nr = folio_nr_pages(folio);3857 int nr = folio_nr_pages(folio);
3936 3858
@@ -4031,7 +3953,10 @@ static int __folio_freeze_and_split_unmapped(struct folio *folio, unsigned int n · 94 unmodified lines
4031 if (ci)3953 if (ci)
4032 swap_cluster_unlock(ci);3954 swap_cluster_unlock(ci);
4033 } else {3955 } else {
4034 split_queue_unlock(ds_queue);3956 if (dequeue_deferred) {
3957 list_lru_unlock(lru);
3958 rcu_read_unlock();
3959 }
4035 return -EAGAIN;3960 return -EAGAIN;
4036 }3961 }
4037 3962
@@ -4397,33 +4322,37 @@ int split_folio_to_list(struct folio *folio, struct list_head *list) · 359 unmodified lines
4397 * queueing THP splits, and that list is (racily observed to be) non-empty.4322 * queueing THP splits, and that list is (racily observed to be) non-empty.
4398 *4323 *
4399 * It is unsafe to call folio_unqueue_deferred_split() until folio refcount is4324 * It is unsafe to call folio_unqueue_deferred_split() until folio refcount is
4400 * zero: because even when split_queue_lock is held, a non-empty _deferred_list4325 * zero: because even when the list_lru lock is held, a non-empty
4401 * might be in use on deferred_split_scan()'s unlocked on-stack list.4326 * _deferred_list might be in use on deferred_split_scan()'s unlocked
4327 * on-stack list.
4402 *4328 *
4403 * If memory cgroups are enabled, split_queue_lock is in the mem_cgroup: it is4329 * The list_lru sublist is determined by folio's memcg: it is therefore
4404 * therefore important to unqueue deferred split before changing folio memcg.4330 * important to unqueue deferred split before changing folio memcg.
4405 */4331 */
4406bool __folio_unqueue_deferred_split(struct folio *folio)4332bool __folio_unqueue_deferred_split(struct folio *folio)
4407{4333{
4408 struct deferred_split *ds_queue;4334 struct mem_cgroup *memcg;
4335 struct list_lru_one *lru;
4336 int nid = folio_nid(folio);
4409 unsigned long flags;4337 unsigned long flags;
4410 bool unqueued = false;4338 bool unqueued = false;
4411 4339
4412 WARN_ON_ONCE(folio_ref_count(folio));4340 WARN_ON_ONCE(folio_ref_count(folio));
4413 WARN_ON_ONCE(!mem_cgroup_disabled() && !folio_memcg_charged(folio));4341 WARN_ON_ONCE(!mem_cgroup_disabled() && !folio_memcg_charged(folio));
4414 4342
4415 ds_queue = folio_split_queue_lock_irqsave(folio, &flags);4343 rcu_read_lock();
4416 if (!list_empty(&folio->_deferred_list)) {4344 memcg = folio_memcg(folio);
4417 ds_queue->split_queue_len--;4345 lru = list_lru_lock_irqsave(&deferred_split_lru, nid, &memcg, &flags);
4346 if (__list_lru_del(&deferred_split_lru, lru, &folio->_deferred_list, nid)) {
4418 if (folio_test_partially_mapped(folio)) {4347 if (folio_test_partially_mapped(folio)) {
4419 folio_clear_partially_mapped(folio);4348 folio_clear_partially_mapped(folio);
4420 mod_mthp_stat(folio_order(folio),4349 mod_mthp_stat(folio_order(folio),
4421 MTHP_STAT_NR_ANON_PARTIALLY_MAPPED, -1);4350 MTHP_STAT_NR_ANON_PARTIALLY_MAPPED, -1);
4422 }4351 }
4423 list_del_init(&folio->_deferred_list);
4424 unqueued = true;4352 unqueued = true;
4425 }4353 }
4426 split_queue_unlock_irqrestore(ds_queue, flags);4354 list_lru_unlock_irqrestore(lru, &flags);
4355 rcu_read_unlock();
4427 4356
4428 return unqueued; /* useful for debug warnings */4357 return unqueued; /* useful for debug warnings */
4429}4358}
@@ -4431,7 +4360,9 @@ bool __folio_unqueue_deferred_split(struct folio *folio) · 1 unmodified line
4431/* partially_mapped=false won't clear PG_partially_mapped folio flag */4360/* partially_mapped=false won't clear PG_partially_mapped folio flag */
4432void deferred_split_folio(struct folio *folio, bool partially_mapped)4361void deferred_split_folio(struct folio *folio, bool partially_mapped)
4433{4362{
4434 struct deferred_split *ds_queue;4363 struct list_lru_one *lru;
4364 int nid;
4365 struct mem_cgroup *memcg;
4435 unsigned long flags;4366 unsigned long flags;
4436 4367
4437 /*4368 /*
@@ -4454,7 +4385,11 @@ void deferred_split_folio(struct folio *folio, bool partially_mapped) · 16 unmodified lines
4454 if (folio_test_swapcache(folio))4385 if (folio_test_swapcache(folio))
4455 return;4386 return;
4456 4387
4457 ds_queue = folio_split_queue_lock_irqsave(folio, &flags);4388 nid = folio_nid(folio);
4389
4390 rcu_read_lock();
4391 memcg = folio_memcg(folio);
4392 lru = list_lru_lock_irqsave(&deferred_split_lru, nid, &memcg, &flags);
4458 if (partially_mapped) {4393 if (partially_mapped) {
4459 if (!folio_test_partially_mapped(folio)) {4394 if (!folio_test_partially_mapped(folio)) {
4460 folio_set_partially_mapped(folio);4395 folio_set_partially_mapped(folio);
@@ -4462,36 +4397,20 @@ void deferred_split_folio(struct folio *folio, bool partially_mapped) · 1 unmodified line
4462 count_vm_event(THP_DEFERRED_SPLIT_PAGE);4397 count_vm_event(THP_DEFERRED_SPLIT_PAGE);
4463 count_mthp_stat(folio_order(folio), MTHP_STAT_SPLIT_DEFERRED);4398 count_mthp_stat(folio_order(folio), MTHP_STAT_SPLIT_DEFERRED);
4464 mod_mthp_stat(folio_order(folio), MTHP_STAT_NR_ANON_PARTIALLY_MAPPED, 1);4399 mod_mthp_stat(folio_order(folio), MTHP_STAT_NR_ANON_PARTIALLY_MAPPED, 1);
4465
4466 }4400 }
4467 } else {4401 } else {
4468 /* partially mapped folios cannot become non-partially mapped */4402 /* partially mapped folios cannot become non-partially mapped */
4469 VM_WARN_ON_FOLIO(folio_test_partially_mapped(folio), folio);4403 VM_WARN_ON_FOLIO(folio_test_partially_mapped(folio), folio);
4470 }4404 }
4471 if (list_empty(&folio->_deferred_list)) {4405 __list_lru_add(&deferred_split_lru, lru, &folio->_deferred_list, nid, memcg);
4472 struct mem_cgroup *memcg;4406 list_lru_unlock_irqrestore(lru, &flags);
4473 4407 rcu_read_unlock();
4474 memcg = folio_split_queue_memcg(folio, ds_queue);
4475 list_add_tail(&folio->_deferred_list, &ds_queue->split_queue);
4476 ds_queue->split_queue_len++;
4477 if (memcg)
4478 set_shrinker_bit(memcg, folio_nid(folio),
4479 shrinker_id(deferred_split_shrinker));
4480 }
4481 split_queue_unlock_irqrestore(ds_queue, flags);
4482}4408}
4483 4409
4484static unsigned long deferred_split_count(struct shrinker *shrink,4410static unsigned long deferred_split_count(struct shrinker *shrink,
4485 struct shrink_control *sc)4411 struct shrink_control *sc)
4486{4412{
4487 struct pglist_data *pgdata = NODE_DATA(sc->nid);4413 return list_lru_shrink_count(&deferred_split_lru, sc);
4488 struct deferred_split *ds_queue = &pgdata->deferred_split_queue;
4489
4490#ifdef CONFIG_MEMCG
4491 if (sc->memcg)
4492 ds_queue = &sc->memcg->deferred_split_queue;
4493#endif
4494 return READ_ONCE(ds_queue->split_queue_len);
4495}4414}
4496 4415
4497static bool thp_underused(struct folio *folio)4416static bool thp_underused(struct folio *folio)
@@ -4521,45 +4440,49 @@ static bool thp_underused(struct folio *folio) · 23 unmodified lines
4521 return false;4440 return false;
4522}4441}
4523 4442
4443static enum lru_status deferred_split_isolate(struct list_head *item,
4444 struct list_lru_one *lru,
4445 void *cb_arg)
4446{
4447 struct folio *folio = container_of(item, struct folio, _deferred_list);
4448 struct list_head *freeable = cb_arg;
4449
4450 if (folio_try_get(folio)) {
4451 list_lru_isolate_move(lru, item, freeable);
4452 return LRU_REMOVED;
4453 }
4454
4455 /*
4456 * We lost race with folio_put(). Read folio state before the
4457 * isolate: folio_unqueue_deferred_split() checks list_empty()
4458 * locklessly, so once removed the folio can be freed any time.
4459 */
4460 if (folio_test_partially_mapped(folio)) {
4461 folio_clear_partially_mapped(folio);
4462 mod_mthp_stat(folio_order(folio),
4463 MTHP_STAT_NR_ANON_PARTIALLY_MAPPED, -1);
4464 }
4465 list_lru_isolate(lru, item);
4466 return LRU_REMOVED;
4467}
4468
4524static unsigned long deferred_split_scan(struct shrinker *shrink,4469static unsigned long deferred_split_scan(struct shrinker *shrink,
4525 struct shrink_control *sc)4470 struct shrink_control *sc)
4526{4471{
4527 struct deferred_split *ds_queue;4472 LIST_HEAD(dispose);
4528 unsigned long flags;
4529 struct folio *folio, *next;4473 struct folio *folio, *next;
4530 int split = 0, i;4474 int split = 0;
4531 struct folio_batch fbatch;4475 unsigned long isolated;
4532
4533 folio_batch_init(&fbatch);
4534 4476
4535retry:4477 isolated = list_lru_shrink_walk_irq(&deferred_split_lru, sc,
4536 ds_queue = split_queue_lock_irqsave(sc->nid, sc->memcg, &flags);4478 deferred_split_isolate, &dispose);
4537 /* Take pin on all head pages to avoid freeing them under us */
4538 list_for_each_entry_safe(folio, next, &ds_queue->split_queue,
4539 _deferred_list) {
4540 if (folio_try_get(folio)) {
4541 folio_batch_add(&fbatch, folio);
4542 } else if (folio_test_partially_mapped(folio)) {
4543 /* We lost race with folio_put() */
4544 folio_clear_partially_mapped(folio);
4545 mod_mthp_stat(folio_order(folio),
4546 MTHP_STAT_NR_ANON_PARTIALLY_MAPPED, -1);
4547 }
4548 list_del_init(&folio->_deferred_list);
4549 ds_queue->split_queue_len--;
4550 if (!--sc->nr_to_scan)
4551 break;
4552 if (!folio_batch_space(&fbatch))
4553 break;
4554 }
4555 split_queue_unlock_irqrestore(ds_queue, flags);
4556 4479
4557 for (i = 0; i < folio_batch_count(&fbatch); i++) {4480 list_for_each_entry_safe(folio, next, &dispose, _deferred_list) {
4558 bool did_split = false;4481 bool did_split = false;
4559 bool underused = false;4482 bool underused = false;
4560 struct deferred_split *fqueue;
4561 4483
4562 folio = fbatch.folios[i];4484 list_del_init(&folio->_deferred_list);
4485
4563 if (!folio_test_partially_mapped(folio)) {4486 if (!folio_test_partially_mapped(folio)) {
4564 /*4487 /*
4565 * See try_to_map_unused_to_zeropage(): we cannot4488 * See try_to_map_unused_to_zeropage(): we cannot
@@ -4588,63 +4511,23 @@ next: · 22 unmodified lines
4588 * underused, then consider it used and don't add it back to4511 * underused, then consider it used and don't add it back to
4589 * split_queue.4512 * split_queue.
4590 */4513 */
4591 if (did_split || !folio_test_partially_mapped(folio))4514 if (!did_split && folio_test_partially_mapped(folio)) {
4592 continue;
4593requeue:4515requeue:
4594 /*4516 rcu_read_lock();
4595 * Add back partially mapped folios, or underused folios that4517 list_lru_add_irq(&deferred_split_lru,
4596 * we could not lock this round.4518 &folio->_deferred_list,
4597 */4519 folio_nid(folio),
4598 fqueue = folio_split_queue_lock_irqsave(folio, &flags);4520 folio_memcg(folio));
4599 if (list_empty(&folio->_deferred_list)) {4521 rcu_read_unlock();
4600 list_add_tail(&folio->_deferred_list, &fqueue->split_queue);
4601 fqueue->split_queue_len++;
4602 }4522 }
4603 split_queue_unlock_irqrestore(fqueue, flags);4523 folio_put(folio);
4604 }
4605 folios_put(&fbatch);
4606
4607 if (sc->nr_to_scan && !list_empty(&ds_queue->split_queue)) {
4608 cond_resched();
4609 goto retry;
4610 }4524 }
4611 4525
4612 /*4526 if (!split && !isolated)
4613 * Stop shrinker if we didn't split any page, but the queue is empty.
4614 * This can happen if pages were freed under us.
4615 */
4616 if (!split && list_empty(&ds_queue->split_queue))
4617 return SHRINK_STOP;4527 return SHRINK_STOP;
4618 return split;4528 return split;
4619}4529}
4620 4530
4621#ifdef CONFIG_MEMCG
4622void reparent_deferred_split_queue(struct mem_cgroup *memcg)
4623{
4624 struct mem_cgroup *parent = parent_mem_cgroup(memcg);
4625 struct deferred_split *ds_queue = &memcg->deferred_split_queue;
4626 struct deferred_split *parent_ds_queue = &parent->deferred_split_queue;
4627 int nid;
4628
4629 spin_lock_irq(&ds_queue->split_queue_lock);
4630 spin_lock_nested(&parent_ds_queue->split_queue_lock, SINGLE_DEPTH_NESTING);
4631
4632 if (!ds_queue->split_queue_len)
4633 goto unlock;
4634
4635 list_splice_tail_init(&ds_queue->split_queue, &parent_ds_queue->split_queue);
4636 parent_ds_queue->split_queue_len += ds_queue->split_queue_len;
4637 ds_queue->split_queue_len = 0;
4638
4639 for_each_node(nid)
4640 set_shrinker_bit(parent, nid, shrinker_id(deferred_split_shrinker));
4641
4642unlock:
4643 spin_unlock(&parent_ds_queue->split_queue_lock);
4644 spin_unlock_irq(&ds_queue->split_queue_lock);
4645}
4646#endif
4647
4648#ifdef CONFIG_DEBUG_FS4531#ifdef CONFIG_DEBUG_FS
4649static void split_huge_pages_all(void)4532static void split_huge_pages_all(void)
4650{4533{
mm/internal.h+1−1
@@ -852,7 +852,7 @@ static inline bool folio_unqueue_deferred_split(struct folio *folio) · 851 unmodified lines
852 /*852 /*
853 * At this point, there is no one trying to add the folio to853 * At this point, there is no one trying to add the folio to
854 * deferred_list. If folio is not in deferred_list, it's safe854 * deferred_list. If folio is not in deferred_list, it's safe
855 * to check without acquiring the split_queue_lock.855 * to check without acquiring the list_lru lock.
856 */856 */
857 if (data_race(list_empty(&folio->_deferred_list)))857 if (data_race(list_empty(&folio->_deferred_list)))
858 return false;858 return false;
mm/khugepaged.c+5−0
@@ -1123,6 +1123,11 @@ static enum scan_result collapse_huge_page(struct mm_struct *mm, unsigned long a · 1122 unmodified lines
1123 if (result != SCAN_SUCCEED)1123 if (result != SCAN_SUCCEED)
1124 goto out_nolock;1124 goto out_nolock;
1125 1125
1126 if (folio_memcg_alloc_deferred(folio)) {
1127 result = SCAN_ALLOC_HUGE_PAGE_FAIL;
1128 goto out_nolock;
1129 }
1130
1126 mmap_read_lock(mm);1131 mmap_read_lock(mm);
1127 result = hugepage_vma_revalidate(mm, address, true, &vma, cc);1132 result = hugepage_vma_revalidate(mm, address, true, &vma, cc);
1128 if (result != SCAN_SUCCEED) {1133 if (result != SCAN_SUCCEED) {
mm/memcontrol.c+3−9
@@ -4143,11 +4143,6 @@ static struct mem_cgroup *mem_cgroup_alloc(struct mem_cgroup *parent) · 4142 unmodified lines
4143 for (i = 0; i < MEMCG_CGWB_FRN_CNT; i++)4143 for (i = 0; i < MEMCG_CGWB_FRN_CNT; i++)
4144 memcg->cgwb_frn[i].done =4144 memcg->cgwb_frn[i].done =
4145 __WB_COMPLETION_INIT(&memcg_cgwb_frn_waitq);4145 __WB_COMPLETION_INIT(&memcg_cgwb_frn_waitq);
4146#endif
4147#ifdef CONFIG_TRANSPARENT_HUGEPAGE
4148 spin_lock_init(&memcg->deferred_split_queue.split_queue_lock);
4149 INIT_LIST_HEAD(&memcg->deferred_split_queue.split_queue);
4150 memcg->deferred_split_queue.split_queue_len = 0;
4151#endif4146#endif
4152 lru_gen_init_memcg(memcg);4147 lru_gen_init_memcg(memcg);
4153 return memcg;4148 return memcg;
@@ -4299,11 +4294,10 @@ static void mem_cgroup_css_offline(struct cgroup_subsys_state *css) · 145 unmodified lines
4299 zswap_memcg_offline_cleanup(memcg);4294 zswap_memcg_offline_cleanup(memcg);
4300 4295
4301 memcg_offline_kmem(memcg);4296 memcg_offline_kmem(memcg);
4302 reparent_deferred_split_queue(memcg);
4303 /*4297 /*
4304 * The reparenting of objcg must be after the reparenting of the4298 * The reparenting of objcg must be after the reparenting of
4305 * list_lru and deferred_split_queue above, which ensures that they will4299 * the list_lru in memcg_offline_kmem(), which ensures that
4306 * not mistakenly get the parent list_lru and deferred_split_queue.4300 * they will not mistakenly get the parent list_lru.
4307 */4301 */
4308 memcg_reparent_objcgs(memcg);4302 memcg_reparent_objcgs(memcg);
4309 reparent_shrinker_deferred(memcg);4303 reparent_shrinker_deferred(memcg);
mm/memory.c+4−0
@@ -5222,6 +5222,10 @@ static struct folio *alloc_anon_folio(struct vm_fault *vmf) · 5221 unmodified lines
5222 folio_put(folio);5222 folio_put(folio);
5223 goto next;5223 goto next;
5224 }5224 }
5225 if (order > 1 && folio_memcg_alloc_deferred(folio)) {
5226 folio_put(folio);
5227 goto fallback;
5228 }
5225 folio_throttle_swaprate(folio, gfp);5229 folio_throttle_swaprate(folio, gfp);
5226 /*5230 /*
5227 * When a folio is not zeroed during allocation5231 * When a folio is not zeroed during allocation
mm/mm_init.c+0−15
@@ -1373,19 +1373,6 @@ static void __init calculate_node_totalpages(struct pglist_data *pgdat, · 1372 unmodified lines
1373 pr_debug("On node %d totalpages: %lu\n", pgdat->node_id, realtotalpages);1373 pr_debug("On node %d totalpages: %lu\n", pgdat->node_id, realtotalpages);
1374}1374}
1375 1375
1376#ifdef CONFIG_TRANSPARENT_HUGEPAGE
1377static void pgdat_init_split_queue(struct pglist_data *pgdat)
1378{
1379 struct deferred_split *ds_queue = &pgdat->deferred_split_queue;
1380
1381 spin_lock_init(&ds_queue->split_queue_lock);
1382 INIT_LIST_HEAD(&ds_queue->split_queue);
1383 ds_queue->split_queue_len = 0;
1384}
1385#else
1386static void pgdat_init_split_queue(struct pglist_data *pgdat) {}
1387#endif
1388
1389#ifdef CONFIG_COMPACTION1376#ifdef CONFIG_COMPACTION
1390static void pgdat_init_kcompactd(struct pglist_data *pgdat)1377static void pgdat_init_kcompactd(struct pglist_data *pgdat)
1391{1378{
@@ -1401,8 +1388,6 @@ static void __meminit pgdat_init_internals(struct pglist_data *pgdat) · 9 unmodified lines
1401 1388
1402 pgdat_resize_init(pgdat);1389 pgdat_resize_init(pgdat);
1403 pgdat_kswapd_lock_init(pgdat);1390 pgdat_kswapd_lock_init(pgdat);
1404
1405 pgdat_init_split_queue(pgdat);
1406 pgdat_init_kcompactd(pgdat);1391 pgdat_init_kcompactd(pgdat);
1407 1392
1408 init_waitqueue_head(&pgdat->kswapd_wait);1393 init_waitqueue_head(&pgdat->kswapd_wait);
mm/swap_state.c+10−0
@@ -465,6 +465,16 @@ static struct folio *__swap_cache_alloc(struct swap_cluster_info *ci, · 464 unmodified lines
465 return ERR_PTR(-ENOMEM);465 return ERR_PTR(-ENOMEM);
466 }466 }
467 467
468 if (order > 1 && folio_memcg_alloc_deferred(folio)) {
469 spin_lock(&ci->lock);
470 __swap_cache_do_del_folio(ci, folio, entry, shadow);
471 spin_unlock(&ci->lock);
472 folio_unlock(folio);
473 /* nr_pages refs from swap cache, 1 from allocation */
474 folio_put_refs(folio, nr_pages + 1);
475 return ERR_PTR(-ENOMEM);
476 }
477
468 /* memsw uncharges swap when folio is added to swap cache */478 /* memsw uncharges swap when folio is added to swap cache */
469 memcg1_swapin(folio);479 memcg1_swapin(folio);
470 if (shadow)480 if (shadow)