Skip to content

Commit a731286

Browse files
kosakitorvalds
authored andcommitted
mm: vmstat: add isolate pages
If the system is running a heavy load of processes then concurrent reclaim can isolate a large number of pages from the LRU. /proc/vmstat and the output generated for an OOM do not show how many pages were isolated. This has been observed during process fork bomb testing (mstctl11 in LTP). This patch shows the information about isolated pages. Reproduced via: ----------------------- % ./hackbench 140 process 1000 => OOM occur active_anon:146 inactive_anon:0 isolated_anon:49245 active_file:79 inactive_file:18 isolated_file:113 unevictable:0 dirty:0 writeback:0 unstable:0 buffer:39 free:370 slab_reclaimable:309 slab_unreclaimable:5492 mapped:53 shmem:15 pagetables:28140 bounce:0 Signed-off-by: KOSAKI Motohiro <[email protected]> Acked-by: Rik van Riel <[email protected]> Acked-by: Wu Fengguang <[email protected]> Reviewed-by: Minchan Kim <[email protected]> Cc: Hugh Dickins <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent b35ea17 commit a731286

File tree

5 files changed

+35
-4
lines changed

5 files changed

+35
-4
lines changed

include/linux/mmzone.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ enum zone_stat_item {
100100
NR_BOUNCE,
101101
NR_VMSCAN_WRITE,
102102
NR_WRITEBACK_TEMP, /* Writeback using temporary buffers */
103+
NR_ISOLATED_ANON, /* Temporary isolated pages from anon lru */
104+
NR_ISOLATED_FILE, /* Temporary isolated pages from file lru */
103105
NR_SHMEM, /* shmem pages (included tmpfs/GEM pages) */
104106
#ifdef CONFIG_NUMA
105107
NUMA_HIT, /* allocated in intended node */

mm/migrate.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ int putback_lru_pages(struct list_head *l)
6767

6868
list_for_each_entry_safe(page, page2, l, lru) {
6969
list_del(&page->lru);
70+
dec_zone_page_state(page, NR_ISOLATED_ANON +
71+
!!page_is_file_cache(page));
7072
putback_lru_page(page);
7173
count++;
7274
}
@@ -698,6 +700,8 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private,
698700
* restored.
699701
*/
700702
list_del(&page->lru);
703+
dec_zone_page_state(page, NR_ISOLATED_ANON +
704+
!!page_is_file_cache(page));
701705
putback_lru_page(page);
702706
}
703707

@@ -742,6 +746,13 @@ int migrate_pages(struct list_head *from,
742746
struct page *page2;
743747
int swapwrite = current->flags & PF_SWAPWRITE;
744748
int rc;
749+
unsigned long flags;
750+
751+
local_irq_save(flags);
752+
list_for_each_entry(page, from, lru)
753+
__inc_zone_page_state(page, NR_ISOLATED_ANON +
754+
!!page_is_file_cache(page));
755+
local_irq_restore(flags);
745756

746757
if (!swapwrite)
747758
current->flags |= PF_SWAPWRITE;

mm/page_alloc.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2134,16 +2134,18 @@ void show_free_areas(void)
21342134
}
21352135
}
21362136

2137-
printk("Active_anon:%lu active_file:%lu inactive_anon:%lu\n"
2138-
" inactive_file:%lu"
2137+
printk("active_anon:%lu inactive_anon:%lu isolated_anon:%lu\n"
2138+
" active_file:%lu inactive_file:%lu isolated_file:%lu\n"
21392139
" unevictable:%lu"
21402140
" dirty:%lu writeback:%lu unstable:%lu buffer:%lu\n"
21412141
" free:%lu slab_reclaimable:%lu slab_unreclaimable:%lu\n"
21422142
" mapped:%lu shmem:%lu pagetables:%lu bounce:%lu\n",
21432143
global_page_state(NR_ACTIVE_ANON),
2144-
global_page_state(NR_ACTIVE_FILE),
21452144
global_page_state(NR_INACTIVE_ANON),
2145+
global_page_state(NR_ISOLATED_ANON),
2146+
global_page_state(NR_ACTIVE_FILE),
21462147
global_page_state(NR_INACTIVE_FILE),
2148+
global_page_state(NR_ISOLATED_FILE),
21472149
global_page_state(NR_UNEVICTABLE),
21482150
global_page_state(NR_FILE_DIRTY),
21492151
global_page_state(NR_WRITEBACK),
@@ -2171,6 +2173,8 @@ void show_free_areas(void)
21712173
" active_file:%lukB"
21722174
" inactive_file:%lukB"
21732175
" unevictable:%lukB"
2176+
" isolated(anon):%lukB"
2177+
" isolated(file):%lukB"
21742178
" present:%lukB"
21752179
" mlocked:%lukB"
21762180
" dirty:%lukB"
@@ -2197,6 +2201,8 @@ void show_free_areas(void)
21972201
K(zone_page_state(zone, NR_ACTIVE_FILE)),
21982202
K(zone_page_state(zone, NR_INACTIVE_FILE)),
21992203
K(zone_page_state(zone, NR_UNEVICTABLE)),
2204+
K(zone_page_state(zone, NR_ISOLATED_ANON)),
2205+
K(zone_page_state(zone, NR_ISOLATED_FILE)),
22002206
K(zone->present_pages),
22012207
K(zone_page_state(zone, NR_MLOCK)),
22022208
K(zone_page_state(zone, NR_FILE_DIRTY)),

mm/vmscan.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1072,6 +1072,8 @@ static unsigned long shrink_inactive_list(unsigned long max_scan,
10721072
unsigned long nr_active;
10731073
unsigned int count[NR_LRU_LISTS] = { 0, };
10741074
int mode = lumpy_reclaim ? ISOLATE_BOTH : ISOLATE_INACTIVE;
1075+
unsigned long nr_anon;
1076+
unsigned long nr_file;
10751077

10761078
nr_taken = sc->isolate_pages(sc->swap_cluster_max,
10771079
&page_list, &nr_scan, sc->order, mode,
@@ -1102,6 +1104,10 @@ static unsigned long shrink_inactive_list(unsigned long max_scan,
11021104
__mod_zone_page_state(zone, NR_INACTIVE_ANON,
11031105
-count[LRU_INACTIVE_ANON]);
11041106

1107+
nr_anon = count[LRU_ACTIVE_ANON] + count[LRU_INACTIVE_ANON];
1108+
nr_file = count[LRU_ACTIVE_FILE] + count[LRU_INACTIVE_FILE];
1109+
__mod_zone_page_state(zone, NR_ISOLATED_ANON, nr_anon);
1110+
__mod_zone_page_state(zone, NR_ISOLATED_FILE, nr_file);
11051111

11061112
reclaim_stat->recent_scanned[0] += count[LRU_INACTIVE_ANON];
11071113
reclaim_stat->recent_scanned[0] += count[LRU_ACTIVE_ANON];
@@ -1169,6 +1175,9 @@ static unsigned long shrink_inactive_list(unsigned long max_scan,
11691175
spin_lock_irq(&zone->lru_lock);
11701176
}
11711177
}
1178+
__mod_zone_page_state(zone, NR_ISOLATED_ANON, -nr_anon);
1179+
__mod_zone_page_state(zone, NR_ISOLATED_FILE, -nr_file);
1180+
11721181
} while (nr_scanned < max_scan);
11731182

11741183
done:
@@ -1279,6 +1288,7 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone,
12791288
__mod_zone_page_state(zone, NR_ACTIVE_FILE, -nr_taken);
12801289
else
12811290
__mod_zone_page_state(zone, NR_ACTIVE_ANON, -nr_taken);
1291+
__mod_zone_page_state(zone, NR_ISOLATED_ANON + file, nr_taken);
12821292
spin_unlock_irq(&zone->lru_lock);
12831293

12841294
while (!list_empty(&l_hold)) {
@@ -1329,7 +1339,7 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone,
13291339
LRU_ACTIVE + file * LRU_FILE);
13301340
move_active_pages_to_lru(zone, &l_inactive,
13311341
LRU_BASE + file * LRU_FILE);
1332-
1342+
__mod_zone_page_state(zone, NR_ISOLATED_ANON + file, -nr_taken);
13331343
spin_unlock_irq(&zone->lru_lock);
13341344
}
13351345

mm/vmstat.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,8 @@ static const char * const vmstat_text[] = {
644644
"nr_bounce",
645645
"nr_vmscan_write",
646646
"nr_writeback_temp",
647+
"nr_isolated_anon",
648+
"nr_isolated_file",
647649
"nr_shmem",
648650
#ifdef CONFIG_NUMA
649651
"numa_hit",

0 commit comments

Comments
 (0)