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: Ying Han <yinghan@google.com> Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Cc: Minchan Kim <minchan.kim@gmail.com> Acked-by: Pavel Emelyanov <xemul@openvz.org> Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: Mel Gorman <mel@csn.ul.ie> Acked-by: Rik 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: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
7b1de5868b
commit
a09ed5e000
|
@ -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)
|
||||||
}
|
}
|
||||||
#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);
|
||||||
|
|
||||||
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)
|
||||||
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);
|
||||||
|
|
46
mm/vmscan.c
46
mm/vmscan.c
|
@ -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,
|
||||||
* 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,
|
||||||
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,
|
||||||
.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,
|
||||||
.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,
|
||||||
.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 @@ loop_again:
|
||||||
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)
|
||||||
.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)
|
||||||
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)
|
||||||
.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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
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 */
|
||||||
|
|
Loading…
Reference in a new issue