Pass the allocation order through shrink_control so shrinkers have
visibility into the order that triggered reclaim.

This allows shrinkers to implement better heuristics, such as detecting
high-order allocation pressure or fragmentation and avoiding eviction
of working sets when reclaim is invoked from kswapd.

Cc: Andrew Morton <[email protected]>
Cc: Dave Chinner <[email protected]>
Cc: Qi Zheng <[email protected]>
Cc: Roman Gushchin <[email protected]>
Cc: Muchun Song <[email protected]>
Cc: David Hildenbrand <[email protected]>
Cc: Lorenzo Stoakes <[email protected]>
Cc: "Liam R. Howlett" <[email protected]>
Cc: Vlastimil Babka <[email protected]>
Cc: Mike Rapoport <[email protected]>
Cc: Suren Baghdasaryan <[email protected]>
Cc: Michal Hocko <[email protected]>
Cc: Johannes Weiner <[email protected]>
Cc: Shakeel Butt <[email protected]>
Cc: Kairui Song <[email protected]>
Cc: Barry Song <[email protected]>
Cc: Axel Rasmussen <[email protected]>
Cc: Yuanchu Xie <[email protected]>
Cc: Wei Xu <[email protected]>
Cc: [email protected]
Cc: [email protected]
Suggested-by: Thomas Hellström <[email protected]>
Signed-off-by: Matthew Brost <[email protected]>
---
 include/linux/shrinker.h |  3 +++
 mm/internal.h            |  4 ++--
 mm/shrinker.c            | 13 ++++++++-----
 mm/vmscan.c              |  7 ++++---
 4 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/include/linux/shrinker.h b/include/linux/shrinker.h
index 1a00be90d93a..7072f693b9be 100644
--- a/include/linux/shrinker.h
+++ b/include/linux/shrinker.h
@@ -37,6 +37,9 @@ struct shrink_control {
        /* current node being shrunk (for NUMA aware shrinkers) */
        int nid;
 
+       /* Allocation order we are currently trying to fulfil. */
+       s8 order;
+
        /*
         * How many objects scan_objects should scan and try to reclaim.
         * This is reset before every call, so it is safe for callees
diff --git a/mm/internal.h b/mm/internal.h
index 5a2ddcf68e0b..ff8671dccf7b 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -1759,8 +1759,8 @@ void __meminit __init_single_page(struct page *page, 
unsigned long pfn,
 void __meminit __init_page_from_nid(unsigned long pfn, int nid);
 
 /* shrinker related functions */
-unsigned long shrink_slab(gfp_t gfp_mask, int nid, struct mem_cgroup *memcg,
-                         int priority);
+unsigned long shrink_slab(gfp_t gfp_mask, int nid, s8 order,
+                         struct mem_cgroup *memcg, int priority);
 
 int shmem_add_to_page_cache(struct folio *folio,
                            struct address_space *mapping,
diff --git a/mm/shrinker.c b/mm/shrinker.c
index 76b3f750cf65..c83f3b3daa08 100644
--- a/mm/shrinker.c
+++ b/mm/shrinker.c
@@ -466,7 +466,7 @@ static unsigned long do_shrink_slab(struct shrink_control 
*shrinkctl,
 }
 
 #ifdef CONFIG_MEMCG
-static unsigned long shrink_slab_memcg(gfp_t gfp_mask, int nid,
+static unsigned long shrink_slab_memcg(gfp_t gfp_mask, int nid, s8 order,
                        struct mem_cgroup *memcg, int priority)
 {
        struct shrinker_info *info;
@@ -528,6 +528,7 @@ static unsigned long shrink_slab_memcg(gfp_t gfp_mask, int 
nid,
                        struct shrink_control sc = {
                                .gfp_mask = gfp_mask,
                                .nid = nid,
+                               .order = order,
                                .memcg = memcg,
                        };
                        struct shrinker *shrinker;
@@ -587,7 +588,7 @@ static unsigned long shrink_slab_memcg(gfp_t gfp_mask, int 
nid,
        return freed;
 }
 #else /* !CONFIG_MEMCG */
-static unsigned long shrink_slab_memcg(gfp_t gfp_mask, int nid,
+static unsigned long shrink_slab_memcg(gfp_t gfp_mask, int nid, s8 order,
                        struct mem_cgroup *memcg, int priority)
 {
        return 0;
@@ -598,6 +599,7 @@ static unsigned long shrink_slab_memcg(gfp_t gfp_mask, int 
nid,
  * shrink_slab - shrink slab caches
  * @gfp_mask: allocation context
  * @nid: node whose slab caches to target
+ * @order: order of allocation
  * @memcg: memory cgroup whose slab caches to target
  * @priority: the reclaim priority
  *
@@ -614,8 +616,8 @@ static unsigned long shrink_slab_memcg(gfp_t gfp_mask, int 
nid,
  *
  * Returns the number of reclaimed slab objects.
  */
-unsigned long shrink_slab(gfp_t gfp_mask, int nid, struct mem_cgroup *memcg,
-                         int priority)
+unsigned long shrink_slab(gfp_t gfp_mask, int nid, s8 order,
+                         struct mem_cgroup *memcg, int priority)
 {
        unsigned long ret, freed = 0;
        struct shrinker *shrinker;
@@ -628,7 +630,7 @@ unsigned long shrink_slab(gfp_t gfp_mask, int nid, struct 
mem_cgroup *memcg,
         * oom.
         */
        if (!mem_cgroup_disabled() && !mem_cgroup_is_root(memcg))
-               return shrink_slab_memcg(gfp_mask, nid, memcg, priority);
+               return shrink_slab_memcg(gfp_mask, nid, order, memcg, priority);
 
        /*
         * lockless algorithm of global shrink.
@@ -656,6 +658,7 @@ unsigned long shrink_slab(gfp_t gfp_mask, int nid, struct 
mem_cgroup *memcg,
                struct shrink_control sc = {
                        .gfp_mask = gfp_mask,
                        .nid = nid,
+                       .order = order,
                        .memcg = memcg,
                };
 
diff --git a/mm/vmscan.c b/mm/vmscan.c
index bd1b1aa12581..a54d14ecad25 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -412,7 +412,7 @@ static unsigned long drop_slab_node(int nid)
 
        memcg = mem_cgroup_iter(NULL, NULL, NULL);
        do {
-               freed += shrink_slab(GFP_KERNEL, nid, memcg, 0);
+               freed += shrink_slab(GFP_KERNEL, nid, 0, memcg, 0);
        } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)) != NULL);
 
        return freed;
@@ -5068,7 +5068,8 @@ static int shrink_one(struct lruvec *lruvec, struct 
scan_control *sc)
 
        success = try_to_shrink_lruvec(lruvec, sc);
 
-       shrink_slab(sc->gfp_mask, pgdat->node_id, memcg, sc->priority);
+       shrink_slab(sc->gfp_mask, pgdat->node_id, sc->order, memcg,
+                   sc->priority);
 
        if (!sc->proactive)
                vmpressure(sc->gfp_mask, memcg, false, sc->nr_scanned - scanned,
@@ -6170,7 +6171,7 @@ static void shrink_node_memcgs(pg_data_t *pgdat, struct 
scan_control *sc)
 
                shrink_lruvec(lruvec, sc);
 
-               shrink_slab(sc->gfp_mask, pgdat->node_id, memcg,
+               shrink_slab(sc->gfp_mask, pgdat->node_id, sc->order, memcg,
                            sc->priority);
 
                /* Record the group's reclaim efficiency */
-- 
2.34.1

Reply via email to