Commit a09ed5e0 authored by Ying Han's avatar Ying Han Committed by Linus Torvalds

vmscan: change shrink_slab() interfaces by passing shrink_control

Consolidate the existing parameters to shrink_slab() into a new
shrink_control struct.  This is needed later to pass the same struct to
shrinkers.
Signed-off-by: default avatarYing Han <yinghan@google.com>
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: Minchan Kim <minchan.kim@gmail.com>
Acked-by: default avatarPavel Emelyanov <xemul@openvz.org>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Mel Gorman <mel@csn.ul.ie>
Acked-by: default avatarRik van Riel <riel@redhat.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: Dave Hansen <dave@linux.vnet.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 7b1de586
...@@ -40,9 +40,13 @@ static void drop_pagecache_sb(struct super_block *sb, void *unused) ...@@ -40,9 +40,13 @@ static void drop_pagecache_sb(struct super_block *sb, void *unused)
static void drop_slab(void) static void drop_slab(void)
{ {
int nr_objects; int nr_objects;
struct shrink_control shrink = {
.gfp_mask = GFP_KERNEL,
.nr_scanned = 1000,
};
do { do {
nr_objects = shrink_slab(1000, GFP_KERNEL, 1000); nr_objects = shrink_slab(&shrink, 1000);
} while (nr_objects > 10); } while (nr_objects > 10);
} }
......
...@@ -1161,6 +1161,15 @@ static inline void sync_mm_rss(struct task_struct *task, struct mm_struct *mm) ...@@ -1161,6 +1161,15 @@ static inline void sync_mm_rss(struct task_struct *task, struct mm_struct *mm)
} }
#endif #endif
/*
* This struct is used to pass information from page reclaim to the shrinkers.
* We consolidate the values for easier extention later.
*/
struct shrink_control {
unsigned long nr_scanned;
gfp_t gfp_mask;
};
/* /*
* A callback you can register to apply pressure to ageable caches. * A callback you can register to apply pressure to ageable caches.
* *
...@@ -1630,8 +1639,8 @@ int in_gate_area_no_mm(unsigned long addr); ...@@ -1630,8 +1639,8 @@ int in_gate_area_no_mm(unsigned long addr);
int drop_caches_sysctl_handler(struct ctl_table *, int, int drop_caches_sysctl_handler(struct ctl_table *, int,
void __user *, size_t *, loff_t *); void __user *, size_t *, loff_t *);
unsigned long shrink_slab(unsigned long scanned, gfp_t gfp_mask, unsigned long shrink_slab(struct shrink_control *shrink,
unsigned long lru_pages); unsigned long lru_pages);
#ifndef CONFIG_MMU #ifndef CONFIG_MMU
#define randomize_va_space 0 #define randomize_va_space 0
......
...@@ -239,7 +239,12 @@ void shake_page(struct page *p, int access) ...@@ -239,7 +239,12 @@ void shake_page(struct page *p, int access)
if (access) { if (access) {
int nr; int nr;
do { do {
nr = shrink_slab(1000, GFP_KERNEL, 1000); struct shrink_control shrink = {
.gfp_mask = GFP_KERNEL,
.nr_scanned = 1000,
};
nr = shrink_slab(&shrink, 1000);
if (page_count(p) == 1) if (page_count(p) == 1)
break; break;
} while (nr > 10); } while (nr > 10);
......
...@@ -222,11 +222,13 @@ EXPORT_SYMBOL(unregister_shrinker); ...@@ -222,11 +222,13 @@ EXPORT_SYMBOL(unregister_shrinker);
* *
* Returns the number of slab objects which we shrunk. * Returns the number of slab objects which we shrunk.
*/ */
unsigned long shrink_slab(unsigned long scanned, gfp_t gfp_mask, unsigned long shrink_slab(struct shrink_control *shrink,
unsigned long lru_pages) unsigned long lru_pages)
{ {
struct shrinker *shrinker; struct shrinker *shrinker;
unsigned long ret = 0; unsigned long ret = 0;
unsigned long scanned = shrink->nr_scanned;
gfp_t gfp_mask = shrink->gfp_mask;
if (scanned == 0) if (scanned == 0)
scanned = SWAP_CLUSTER_MAX; scanned = SWAP_CLUSTER_MAX;
...@@ -2035,7 +2037,8 @@ static bool all_unreclaimable(struct zonelist *zonelist, ...@@ -2035,7 +2037,8 @@ static bool all_unreclaimable(struct zonelist *zonelist,
* else, the number of pages reclaimed * else, the number of pages reclaimed
*/ */
static unsigned long do_try_to_free_pages(struct zonelist *zonelist, static unsigned long do_try_to_free_pages(struct zonelist *zonelist,
struct scan_control *sc) struct scan_control *sc,
struct shrink_control *shrink)
{ {
int priority; int priority;
unsigned long total_scanned = 0; unsigned long total_scanned = 0;
...@@ -2069,7 +2072,8 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, ...@@ -2069,7 +2072,8 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist,
lru_pages += zone_reclaimable_pages(zone); lru_pages += zone_reclaimable_pages(zone);
} }
shrink_slab(sc->nr_scanned, sc->gfp_mask, lru_pages); shrink->nr_scanned = sc->nr_scanned;
shrink_slab(shrink, lru_pages);
if (reclaim_state) { if (reclaim_state) {
sc->nr_reclaimed += reclaim_state->reclaimed_slab; sc->nr_reclaimed += reclaim_state->reclaimed_slab;
reclaim_state->reclaimed_slab = 0; reclaim_state->reclaimed_slab = 0;
...@@ -2141,12 +2145,15 @@ unsigned long try_to_free_pages(struct zonelist *zonelist, int order, ...@@ -2141,12 +2145,15 @@ unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
.mem_cgroup = NULL, .mem_cgroup = NULL,
.nodemask = nodemask, .nodemask = nodemask,
}; };
struct shrink_control shrink = {
.gfp_mask = sc.gfp_mask,
};
trace_mm_vmscan_direct_reclaim_begin(order, trace_mm_vmscan_direct_reclaim_begin(order,
sc.may_writepage, sc.may_writepage,
gfp_mask); gfp_mask);
nr_reclaimed = do_try_to_free_pages(zonelist, &sc); nr_reclaimed = do_try_to_free_pages(zonelist, &sc, &shrink);
trace_mm_vmscan_direct_reclaim_end(nr_reclaimed); trace_mm_vmscan_direct_reclaim_end(nr_reclaimed);
...@@ -2206,17 +2213,20 @@ unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem_cont, ...@@ -2206,17 +2213,20 @@ unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem_cont,
.order = 0, .order = 0,
.mem_cgroup = mem_cont, .mem_cgroup = mem_cont,
.nodemask = NULL, /* we don't care the placement */ .nodemask = NULL, /* we don't care the placement */
.gfp_mask = (gfp_mask & GFP_RECLAIM_MASK) |
(GFP_HIGHUSER_MOVABLE & ~GFP_RECLAIM_MASK),
};
struct shrink_control shrink = {
.gfp_mask = sc.gfp_mask,
}; };
sc.gfp_mask = (gfp_mask & GFP_RECLAIM_MASK) |
(GFP_HIGHUSER_MOVABLE & ~GFP_RECLAIM_MASK);
zonelist = NODE_DATA(numa_node_id())->node_zonelists; zonelist = NODE_DATA(numa_node_id())->node_zonelists;
trace_mm_vmscan_memcg_reclaim_begin(0, trace_mm_vmscan_memcg_reclaim_begin(0,
sc.may_writepage, sc.may_writepage,
sc.gfp_mask); sc.gfp_mask);
nr_reclaimed = do_try_to_free_pages(zonelist, &sc); nr_reclaimed = do_try_to_free_pages(zonelist, &sc, &shrink);
trace_mm_vmscan_memcg_reclaim_end(nr_reclaimed); trace_mm_vmscan_memcg_reclaim_end(nr_reclaimed);
...@@ -2344,6 +2354,9 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order, ...@@ -2344,6 +2354,9 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order,
.order = order, .order = order,
.mem_cgroup = NULL, .mem_cgroup = NULL,
}; };
struct shrink_control shrink = {
.gfp_mask = sc.gfp_mask,
};
loop_again: loop_again:
total_scanned = 0; total_scanned = 0;
sc.nr_reclaimed = 0; sc.nr_reclaimed = 0;
...@@ -2443,8 +2456,8 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order, ...@@ -2443,8 +2456,8 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order,
end_zone, 0)) end_zone, 0))
shrink_zone(priority, zone, &sc); shrink_zone(priority, zone, &sc);
reclaim_state->reclaimed_slab = 0; reclaim_state->reclaimed_slab = 0;
nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL, shrink.nr_scanned = sc.nr_scanned;
lru_pages); nr_slab = shrink_slab(&shrink, lru_pages);
sc.nr_reclaimed += reclaim_state->reclaimed_slab; sc.nr_reclaimed += reclaim_state->reclaimed_slab;
total_scanned += sc.nr_scanned; total_scanned += sc.nr_scanned;
...@@ -2796,7 +2809,10 @@ unsigned long shrink_all_memory(unsigned long nr_to_reclaim) ...@@ -2796,7 +2809,10 @@ unsigned long shrink_all_memory(unsigned long nr_to_reclaim)
.swappiness = vm_swappiness, .swappiness = vm_swappiness,
.order = 0, .order = 0,
}; };
struct zonelist * zonelist = node_zonelist(numa_node_id(), sc.gfp_mask); struct shrink_control shrink = {
.gfp_mask = sc.gfp_mask,
};
struct zonelist *zonelist = node_zonelist(numa_node_id(), sc.gfp_mask);
struct task_struct *p = current; struct task_struct *p = current;
unsigned long nr_reclaimed; unsigned long nr_reclaimed;
...@@ -2805,7 +2821,7 @@ unsigned long shrink_all_memory(unsigned long nr_to_reclaim) ...@@ -2805,7 +2821,7 @@ unsigned long shrink_all_memory(unsigned long nr_to_reclaim)
reclaim_state.reclaimed_slab = 0; reclaim_state.reclaimed_slab = 0;
p->reclaim_state = &reclaim_state; p->reclaim_state = &reclaim_state;
nr_reclaimed = do_try_to_free_pages(zonelist, &sc); nr_reclaimed = do_try_to_free_pages(zonelist, &sc, &shrink);
p->reclaim_state = NULL; p->reclaim_state = NULL;
lockdep_clear_current_reclaim_state(); lockdep_clear_current_reclaim_state();
...@@ -2980,6 +2996,9 @@ static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) ...@@ -2980,6 +2996,9 @@ static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
.swappiness = vm_swappiness, .swappiness = vm_swappiness,
.order = order, .order = order,
}; };
struct shrink_control shrink = {
.gfp_mask = sc.gfp_mask,
};
unsigned long nr_slab_pages0, nr_slab_pages1; unsigned long nr_slab_pages0, nr_slab_pages1;
cond_resched(); cond_resched();
...@@ -3006,6 +3025,7 @@ static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) ...@@ -3006,6 +3025,7 @@ static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
} }
nr_slab_pages0 = zone_page_state(zone, NR_SLAB_RECLAIMABLE); nr_slab_pages0 = zone_page_state(zone, NR_SLAB_RECLAIMABLE);
shrink.nr_scanned = sc.nr_scanned;
if (nr_slab_pages0 > zone->min_slab_pages) { if (nr_slab_pages0 > zone->min_slab_pages) {
/* /*
* shrink_slab() does not currently allow us to determine how * shrink_slab() does not currently allow us to determine how
...@@ -3021,7 +3041,7 @@ static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) ...@@ -3021,7 +3041,7 @@ static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
unsigned long lru_pages = zone_reclaimable_pages(zone); unsigned long lru_pages = zone_reclaimable_pages(zone);
/* No reclaimable slab or very low memory pressure */ /* No reclaimable slab or very low memory pressure */
if (!shrink_slab(sc.nr_scanned, gfp_mask, lru_pages)) if (!shrink_slab(&shrink, lru_pages))
break; break;
/* Freed enough memory */ /* Freed enough memory */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment