aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/trace/postprocess/trace-vmscan-postprocess.pl8
-rw-r--r--include/linux/memcontrol.h3
-rw-r--r--include/linux/mmzone.h8
-rw-r--r--include/linux/swap.h7
-rw-r--r--include/trace/events/vmscan.h8
-rw-r--r--mm/compaction.c3
-rw-r--r--mm/memcontrol.c3
-rw-r--r--mm/vmscan.c37
8 files changed, 43 insertions, 34 deletions
diff --git a/Documentation/trace/postprocess/trace-vmscan-postprocess.pl b/Documentation/trace/postprocess/trace-vmscan-postprocess.pl
index 12cecc83cd91..4a37c4759cd2 100644
--- a/Documentation/trace/postprocess/trace-vmscan-postprocess.pl
+++ b/Documentation/trace/postprocess/trace-vmscan-postprocess.pl
@@ -379,10 +379,10 @@ EVENT_PROCESS:
379 379
380 # To closer match vmstat scanning statistics, only count isolate_both 380 # To closer match vmstat scanning statistics, only count isolate_both
381 # and isolate_inactive as scanning. isolate_active is rotation 381 # and isolate_inactive as scanning. isolate_active is rotation
382 # isolate_inactive == 0 382 # isolate_inactive == 1
383 # isolate_active == 1 383 # isolate_active == 2
384 # isolate_both == 2 384 # isolate_both == 3
385 if ($isolate_mode != 1) { 385 if ($isolate_mode != 2) {
386 $perprocesspid{$process_pid}->{HIGH_NR_SCANNED} += $nr_scanned; 386 $perprocesspid{$process_pid}->{HIGH_NR_SCANNED} += $nr_scanned;
387 } 387 }
388 $perprocesspid{$process_pid}->{HIGH_NR_CONTIG_DIRTY} += $nr_contig_dirty; 388 $perprocesspid{$process_pid}->{HIGH_NR_CONTIG_DIRTY} += $nr_contig_dirty;
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 343bd7661f2a..ac797fa03ef8 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -35,7 +35,8 @@ enum mem_cgroup_page_stat_item {
35extern unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan, 35extern unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan,
36 struct list_head *dst, 36 struct list_head *dst,
37 unsigned long *scanned, int order, 37 unsigned long *scanned, int order,
38 int mode, struct zone *z, 38 isolate_mode_t mode,
39 struct zone *z,
39 struct mem_cgroup *mem_cont, 40 struct mem_cgroup *mem_cont,
40 int active, int file); 41 int active, int file);
41 42
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index be1ac8d7789b..436ce6e7a446 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -164,6 +164,14 @@ static inline int is_unevictable_lru(enum lru_list l)
164#define LRU_ALL_EVICTABLE (LRU_ALL_FILE | LRU_ALL_ANON) 164#define LRU_ALL_EVICTABLE (LRU_ALL_FILE | LRU_ALL_ANON)
165#define LRU_ALL ((1 << NR_LRU_LISTS) - 1) 165#define LRU_ALL ((1 << NR_LRU_LISTS) - 1)
166 166
167/* Isolate inactive pages */
168#define ISOLATE_INACTIVE ((__force isolate_mode_t)0x1)
169/* Isolate active pages */
170#define ISOLATE_ACTIVE ((__force isolate_mode_t)0x2)
171
172/* LRU Isolation modes. */
173typedef unsigned __bitwise__ isolate_mode_t;
174
167enum zone_watermarks { 175enum zone_watermarks {
168 WMARK_MIN, 176 WMARK_MIN,
169 WMARK_LOW, 177 WMARK_LOW,
diff --git a/include/linux/swap.h b/include/linux/swap.h
index c71f84bb62ec..1e22e126d2ac 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -243,15 +243,10 @@ static inline void lru_cache_add_file(struct page *page)
243 __lru_cache_add(page, LRU_INACTIVE_FILE); 243 __lru_cache_add(page, LRU_INACTIVE_FILE);
244} 244}
245 245
246/* LRU Isolation modes. */
247#define ISOLATE_INACTIVE 0 /* Isolate inactive pages. */
248#define ISOLATE_ACTIVE 1 /* Isolate active pages. */
249#define ISOLATE_BOTH 2 /* Isolate both active and inactive pages. */
250
251/* linux/mm/vmscan.c */ 246/* linux/mm/vmscan.c */
252extern unsigned long try_to_free_pages(struct zonelist *zonelist, int order, 247extern unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
253 gfp_t gfp_mask, nodemask_t *mask); 248 gfp_t gfp_mask, nodemask_t *mask);
254extern int __isolate_lru_page(struct page *page, int mode, int file); 249extern int __isolate_lru_page(struct page *page, isolate_mode_t mode, int file);
255extern unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem, 250extern unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem,
256 gfp_t gfp_mask, bool noswap); 251 gfp_t gfp_mask, bool noswap);
257extern unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *mem, 252extern unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *mem,
diff --git a/include/trace/events/vmscan.h b/include/trace/events/vmscan.h
index 36851f7f13da..edc4b3d25a2d 100644
--- a/include/trace/events/vmscan.h
+++ b/include/trace/events/vmscan.h
@@ -266,7 +266,7 @@ DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template,
266 unsigned long nr_lumpy_taken, 266 unsigned long nr_lumpy_taken,
267 unsigned long nr_lumpy_dirty, 267 unsigned long nr_lumpy_dirty,
268 unsigned long nr_lumpy_failed, 268 unsigned long nr_lumpy_failed,
269 int isolate_mode), 269 isolate_mode_t isolate_mode),
270 270
271 TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode), 271 TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode),
272 272
@@ -278,7 +278,7 @@ DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template,
278 __field(unsigned long, nr_lumpy_taken) 278 __field(unsigned long, nr_lumpy_taken)
279 __field(unsigned long, nr_lumpy_dirty) 279 __field(unsigned long, nr_lumpy_dirty)
280 __field(unsigned long, nr_lumpy_failed) 280 __field(unsigned long, nr_lumpy_failed)
281 __field(int, isolate_mode) 281 __field(isolate_mode_t, isolate_mode)
282 ), 282 ),
283 283
284 TP_fast_assign( 284 TP_fast_assign(
@@ -312,7 +312,7 @@ DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_lru_isolate,
312 unsigned long nr_lumpy_taken, 312 unsigned long nr_lumpy_taken,
313 unsigned long nr_lumpy_dirty, 313 unsigned long nr_lumpy_dirty,
314 unsigned long nr_lumpy_failed, 314 unsigned long nr_lumpy_failed,
315 int isolate_mode), 315 isolate_mode_t isolate_mode),
316 316
317 TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode) 317 TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode)
318 318
@@ -327,7 +327,7 @@ DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_memcg_isolate,
327 unsigned long nr_lumpy_taken, 327 unsigned long nr_lumpy_taken,
328 unsigned long nr_lumpy_dirty, 328 unsigned long nr_lumpy_dirty,
329 unsigned long nr_lumpy_failed, 329 unsigned long nr_lumpy_failed,
330 int isolate_mode), 330 isolate_mode_t isolate_mode),
331 331
332 TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode) 332 TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode)
333 333
diff --git a/mm/compaction.c b/mm/compaction.c
index b2977a5d659a..47f717fa4233 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -349,7 +349,8 @@ static isolate_migrate_t isolate_migratepages(struct zone *zone,
349 } 349 }
350 350
351 /* Try isolate the page */ 351 /* Try isolate the page */
352 if (__isolate_lru_page(page, ISOLATE_BOTH, 0) != 0) 352 if (__isolate_lru_page(page,
353 ISOLATE_ACTIVE|ISOLATE_INACTIVE, 0) != 0)
353 continue; 354 continue;
354 355
355 VM_BUG_ON(PageTransCompound(page)); 356 VM_BUG_ON(PageTransCompound(page));
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 3508777837c7..2d5755544afe 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1185,7 +1185,8 @@ mem_cgroup_get_reclaim_stat_from_page(struct page *page)
1185unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan, 1185unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan,
1186 struct list_head *dst, 1186 struct list_head *dst,
1187 unsigned long *scanned, int order, 1187 unsigned long *scanned, int order,
1188 int mode, struct zone *z, 1188 isolate_mode_t mode,
1189 struct zone *z,
1189 struct mem_cgroup *mem_cont, 1190 struct mem_cgroup *mem_cont,
1190 int active, int file) 1191 int active, int file)
1191{ 1192{
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 9fdfce7ba403..ec6dbcb976d1 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1012,23 +1012,27 @@ keep_lumpy:
1012 * 1012 *
1013 * returns 0 on success, -ve errno on failure. 1013 * returns 0 on success, -ve errno on failure.
1014 */ 1014 */
1015int __isolate_lru_page(struct page *page, int mode, int file) 1015int __isolate_lru_page(struct page *page, isolate_mode_t mode, int file)
1016{ 1016{
1017 bool all_lru_mode;
1017 int ret = -EINVAL; 1018 int ret = -EINVAL;
1018 1019
1019 /* Only take pages on the LRU. */ 1020 /* Only take pages on the LRU. */
1020 if (!PageLRU(page)) 1021 if (!PageLRU(page))
1021 return ret; 1022 return ret;
1022 1023
1024 all_lru_mode = (mode & (ISOLATE_ACTIVE|ISOLATE_INACTIVE)) ==
1025 (ISOLATE_ACTIVE|ISOLATE_INACTIVE);
1026
1023 /* 1027 /*
1024 * When checking the active state, we need to be sure we are 1028 * When checking the active state, we need to be sure we are
1025 * dealing with comparible boolean values. Take the logical not 1029 * dealing with comparible boolean values. Take the logical not
1026 * of each. 1030 * of each.
1027 */ 1031 */
1028 if (mode != ISOLATE_BOTH && (!PageActive(page) != !mode)) 1032 if (!all_lru_mode && !PageActive(page) != !(mode & ISOLATE_ACTIVE))
1029 return ret; 1033 return ret;
1030 1034
1031 if (mode != ISOLATE_BOTH && page_is_file_cache(page) != file) 1035 if (!all_lru_mode && !!page_is_file_cache(page) != file)
1032 return ret; 1036 return ret;
1033 1037
1034 /* 1038 /*
@@ -1076,7 +1080,8 @@ int __isolate_lru_page(struct page *page, int mode, int file)
1076 */ 1080 */
1077static unsigned long isolate_lru_pages(unsigned long nr_to_scan, 1081static unsigned long isolate_lru_pages(unsigned long nr_to_scan,
1078 struct list_head *src, struct list_head *dst, 1082 struct list_head *src, struct list_head *dst,
1079 unsigned long *scanned, int order, int mode, int file) 1083 unsigned long *scanned, int order, isolate_mode_t mode,
1084 int file)
1080{ 1085{
1081 unsigned long nr_taken = 0; 1086 unsigned long nr_taken = 0;
1082 unsigned long nr_lumpy_taken = 0; 1087 unsigned long nr_lumpy_taken = 0;
@@ -1201,8 +1206,8 @@ static unsigned long isolate_lru_pages(unsigned long nr_to_scan,
1201static unsigned long isolate_pages_global(unsigned long nr, 1206static unsigned long isolate_pages_global(unsigned long nr,
1202 struct list_head *dst, 1207 struct list_head *dst,
1203 unsigned long *scanned, int order, 1208 unsigned long *scanned, int order,
1204 int mode, struct zone *z, 1209 isolate_mode_t mode,
1205 int active, int file) 1210 struct zone *z, int active, int file)
1206{ 1211{
1207 int lru = LRU_BASE; 1212 int lru = LRU_BASE;
1208 if (active) 1213 if (active)
@@ -1448,6 +1453,7 @@ shrink_inactive_list(unsigned long nr_to_scan, struct zone *zone,
1448 unsigned long nr_taken; 1453 unsigned long nr_taken;
1449 unsigned long nr_anon; 1454 unsigned long nr_anon;
1450 unsigned long nr_file; 1455 unsigned long nr_file;
1456 isolate_mode_t reclaim_mode = ISOLATE_INACTIVE;
1451 1457
1452 while (unlikely(too_many_isolated(zone, file, sc))) { 1458 while (unlikely(too_many_isolated(zone, file, sc))) {
1453 congestion_wait(BLK_RW_ASYNC, HZ/10); 1459 congestion_wait(BLK_RW_ASYNC, HZ/10);
@@ -1458,15 +1464,15 @@ shrink_inactive_list(unsigned long nr_to_scan, struct zone *zone,
1458 } 1464 }
1459 1465
1460 set_reclaim_mode(priority, sc, false); 1466 set_reclaim_mode(priority, sc, false);
1467 if (sc->reclaim_mode & RECLAIM_MODE_LUMPYRECLAIM)
1468 reclaim_mode |= ISOLATE_ACTIVE;
1469
1461 lru_add_drain(); 1470 lru_add_drain();
1462 spin_lock_irq(&zone->lru_lock); 1471 spin_lock_irq(&zone->lru_lock);
1463 1472
1464 if (scanning_global_lru(sc)) { 1473 if (scanning_global_lru(sc)) {
1465 nr_taken = isolate_pages_global(nr_to_scan, 1474 nr_taken = isolate_pages_global(nr_to_scan, &page_list,
1466 &page_list, &nr_scanned, sc->order, 1475 &nr_scanned, sc->order, reclaim_mode, zone, 0, file);
1467 sc->reclaim_mode & RECLAIM_MODE_LUMPYRECLAIM ?
1468 ISOLATE_BOTH : ISOLATE_INACTIVE,
1469 zone, 0, file);
1470 zone->pages_scanned += nr_scanned; 1476 zone->pages_scanned += nr_scanned;
1471 if (current_is_kswapd()) 1477 if (current_is_kswapd())
1472 __count_zone_vm_events(PGSCAN_KSWAPD, zone, 1478 __count_zone_vm_events(PGSCAN_KSWAPD, zone,
@@ -1475,12 +1481,9 @@ shrink_inactive_list(unsigned long nr_to_scan, struct zone *zone,
1475 __count_zone_vm_events(PGSCAN_DIRECT, zone, 1481 __count_zone_vm_events(PGSCAN_DIRECT, zone,
1476 nr_scanned); 1482 nr_scanned);
1477 } else { 1483 } else {
1478 nr_taken = mem_cgroup_isolate_pages(nr_to_scan, 1484 nr_taken = mem_cgroup_isolate_pages(nr_to_scan, &page_list,
1479 &page_list, &nr_scanned, sc->order, 1485 &nr_scanned, sc->order, reclaim_mode, zone,
1480 sc->reclaim_mode & RECLAIM_MODE_LUMPYRECLAIM ? 1486 sc->mem_cgroup, 0, file);
1481 ISOLATE_BOTH : ISOLATE_INACTIVE,
1482 zone, sc->mem_cgroup,
1483 0, file);
1484 /* 1487 /*
1485 * mem_cgroup_isolate_pages() keeps track of 1488 * mem_cgroup_isolate_pages() keeps track of
1486 * scanned pages on its own. 1489 * scanned pages on its own.