aboutsummaryrefslogtreecommitdiffstats
path: root/mm/vmstat.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/vmstat.c')
-rw-r--r--mm/vmstat.c102
1 files changed, 102 insertions, 0 deletions
diff --git a/mm/vmstat.c b/mm/vmstat.c
index 1b12d390dc68..1284f89fca08 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -22,6 +22,8 @@
22#include <linux/writeback.h> 22#include <linux/writeback.h>
23#include <linux/compaction.h> 23#include <linux/compaction.h>
24#include <linux/mm_inline.h> 24#include <linux/mm_inline.h>
25#include <linux/page_ext.h>
26#include <linux/page_owner.h>
25 27
26#include "internal.h" 28#include "internal.h"
27 29
@@ -898,6 +900,7 @@ const char * const vmstat_text[] = {
898#ifdef CONFIG_DEBUG_VM_VMACACHE 900#ifdef CONFIG_DEBUG_VM_VMACACHE
899 "vmacache_find_calls", 901 "vmacache_find_calls",
900 "vmacache_find_hits", 902 "vmacache_find_hits",
903 "vmacache_full_flushes",
901#endif 904#endif
902#endif /* CONFIG_VM_EVENTS_COUNTERS */ 905#endif /* CONFIG_VM_EVENTS_COUNTERS */
903}; 906};
@@ -1017,6 +1020,104 @@ static int pagetypeinfo_showblockcount(struct seq_file *m, void *arg)
1017 return 0; 1020 return 0;
1018} 1021}
1019 1022
1023#ifdef CONFIG_PAGE_OWNER
1024static void pagetypeinfo_showmixedcount_print(struct seq_file *m,
1025 pg_data_t *pgdat,
1026 struct zone *zone)
1027{
1028 struct page *page;
1029 struct page_ext *page_ext;
1030 unsigned long pfn = zone->zone_start_pfn, block_end_pfn;
1031 unsigned long end_pfn = pfn + zone->spanned_pages;
1032 unsigned long count[MIGRATE_TYPES] = { 0, };
1033 int pageblock_mt, page_mt;
1034 int i;
1035
1036 /* Scan block by block. First and last block may be incomplete */
1037 pfn = zone->zone_start_pfn;
1038
1039 /*
1040 * Walk the zone in pageblock_nr_pages steps. If a page block spans
1041 * a zone boundary, it will be double counted between zones. This does
1042 * not matter as the mixed block count will still be correct
1043 */
1044 for (; pfn < end_pfn; ) {
1045 if (!pfn_valid(pfn)) {
1046 pfn = ALIGN(pfn + 1, MAX_ORDER_NR_PAGES);
1047 continue;
1048 }
1049
1050 block_end_pfn = ALIGN(pfn + 1, pageblock_nr_pages);
1051 block_end_pfn = min(block_end_pfn, end_pfn);
1052
1053 page = pfn_to_page(pfn);
1054 pageblock_mt = get_pfnblock_migratetype(page, pfn);
1055
1056 for (; pfn < block_end_pfn; pfn++) {
1057 if (!pfn_valid_within(pfn))
1058 continue;
1059
1060 page = pfn_to_page(pfn);
1061 if (PageBuddy(page)) {
1062 pfn += (1UL << page_order(page)) - 1;
1063 continue;
1064 }
1065
1066 if (PageReserved(page))
1067 continue;
1068
1069 page_ext = lookup_page_ext(page);
1070
1071 if (!test_bit(PAGE_EXT_OWNER, &page_ext->flags))
1072 continue;
1073
1074 page_mt = gfpflags_to_migratetype(page_ext->gfp_mask);
1075 if (pageblock_mt != page_mt) {
1076 if (is_migrate_cma(pageblock_mt))
1077 count[MIGRATE_MOVABLE]++;
1078 else
1079 count[pageblock_mt]++;
1080
1081 pfn = block_end_pfn;
1082 break;
1083 }
1084 pfn += (1UL << page_ext->order) - 1;
1085 }
1086 }
1087
1088 /* Print counts */
1089 seq_printf(m, "Node %d, zone %8s ", pgdat->node_id, zone->name);
1090 for (i = 0; i < MIGRATE_TYPES; i++)
1091 seq_printf(m, "%12lu ", count[i]);
1092 seq_putc(m, '\n');
1093}
1094#endif /* CONFIG_PAGE_OWNER */
1095
1096/*
1097 * Print out the number of pageblocks for each migratetype that contain pages
1098 * of other types. This gives an indication of how well fallbacks are being
1099 * contained by rmqueue_fallback(). It requires information from PAGE_OWNER
1100 * to determine what is going on
1101 */
1102static void pagetypeinfo_showmixedcount(struct seq_file *m, pg_data_t *pgdat)
1103{
1104#ifdef CONFIG_PAGE_OWNER
1105 int mtype;
1106
1107 if (!page_owner_inited)
1108 return;
1109
1110 drain_all_pages(NULL);
1111
1112 seq_printf(m, "\n%-23s", "Number of mixed blocks ");
1113 for (mtype = 0; mtype < MIGRATE_TYPES; mtype++)
1114 seq_printf(m, "%12s ", migratetype_names[mtype]);
1115 seq_putc(m, '\n');
1116
1117 walk_zones_in_node(m, pgdat, pagetypeinfo_showmixedcount_print);
1118#endif /* CONFIG_PAGE_OWNER */
1119}
1120
1020/* 1121/*
1021 * This prints out statistics in relation to grouping pages by mobility. 1122 * This prints out statistics in relation to grouping pages by mobility.
1022 * It is expensive to collect so do not constantly read the file. 1123 * It is expensive to collect so do not constantly read the file.
@@ -1034,6 +1135,7 @@ static int pagetypeinfo_show(struct seq_file *m, void *arg)
1034 seq_putc(m, '\n'); 1135 seq_putc(m, '\n');
1035 pagetypeinfo_showfree(m, pgdat); 1136 pagetypeinfo_showfree(m, pgdat);
1036 pagetypeinfo_showblockcount(m, pgdat); 1137 pagetypeinfo_showblockcount(m, pgdat);
1138 pagetypeinfo_showmixedcount(m, pgdat);
1037 1139
1038 return 0; 1140 return 0;
1039} 1141}