aboutsummaryrefslogtreecommitdiffstats
path: root/mm/vmstat.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/vmstat.c')
-rw-r--r--mm/vmstat.c253
1 files changed, 252 insertions, 1 deletions
diff --git a/mm/vmstat.c b/mm/vmstat.c
index fa12ea3051fb..7759941d4e77 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -16,6 +16,7 @@
16#include <linux/cpu.h> 16#include <linux/cpu.h>
17#include <linux/vmstat.h> 17#include <linux/vmstat.h>
18#include <linux/sched.h> 18#include <linux/sched.h>
19#include <linux/math64.h>
19 20
20#ifdef CONFIG_VM_EVENT_COUNTERS 21#ifdef CONFIG_VM_EVENT_COUNTERS
21DEFINE_PER_CPU(struct vm_event_state, vm_event_states) = {{0}}; 22DEFINE_PER_CPU(struct vm_event_state, vm_event_states) = {{0}};
@@ -379,7 +380,86 @@ void zone_statistics(struct zone *preferred_zone, struct zone *z)
379} 380}
380#endif 381#endif
381 382
382#ifdef CONFIG_PROC_FS 383#ifdef CONFIG_COMPACTION
384struct contig_page_info {
385 unsigned long free_pages;
386 unsigned long free_blocks_total;
387 unsigned long free_blocks_suitable;
388};
389
390/*
391 * Calculate the number of free pages in a zone, how many contiguous
392 * pages are free and how many are large enough to satisfy an allocation of
393 * the target size. Note that this function makes no attempt to estimate
394 * how many suitable free blocks there *might* be if MOVABLE pages were
395 * migrated. Calculating that is possible, but expensive and can be
396 * figured out from userspace
397 */
398static void fill_contig_page_info(struct zone *zone,
399 unsigned int suitable_order,
400 struct contig_page_info *info)
401{
402 unsigned int order;
403
404 info->free_pages = 0;
405 info->free_blocks_total = 0;
406 info->free_blocks_suitable = 0;
407
408 for (order = 0; order < MAX_ORDER; order++) {
409 unsigned long blocks;
410
411 /* Count number of free blocks */
412 blocks = zone->free_area[order].nr_free;
413 info->free_blocks_total += blocks;
414
415 /* Count free base pages */
416 info->free_pages += blocks << order;
417
418 /* Count the suitable free blocks */
419 if (order >= suitable_order)
420 info->free_blocks_suitable += blocks <<
421 (order - suitable_order);
422 }
423}
424
425/*
426 * A fragmentation index only makes sense if an allocation of a requested
427 * size would fail. If that is true, the fragmentation index indicates
428 * whether external fragmentation or a lack of memory was the problem.
429 * The value can be used to determine if page reclaim or compaction
430 * should be used
431 */
432static int __fragmentation_index(unsigned int order, struct contig_page_info *info)
433{
434 unsigned long requested = 1UL << order;
435
436 if (!info->free_blocks_total)
437 return 0;
438
439 /* Fragmentation index only makes sense when a request would fail */
440 if (info->free_blocks_suitable)
441 return -1000;
442
443 /*
444 * Index is between 0 and 1 so return within 3 decimal places
445 *
446 * 0 => allocation would fail due to lack of memory
447 * 1 => allocation would fail due to fragmentation
448 */
449 return 1000 - div_u64( (1000+(div_u64(info->free_pages * 1000ULL, requested))), info->free_blocks_total);
450}
451
452/* Same as __fragmentation index but allocs contig_page_info on stack */
453int fragmentation_index(struct zone *zone, unsigned int order)
454{
455 struct contig_page_info info;
456
457 fill_contig_page_info(zone, order, &info);
458 return __fragmentation_index(order, &info);
459}
460#endif
461
462#if defined(CONFIG_PROC_FS) || defined(CONFIG_COMPACTION)
383#include <linux/proc_fs.h> 463#include <linux/proc_fs.h>
384#include <linux/seq_file.h> 464#include <linux/seq_file.h>
385 465
@@ -432,7 +512,9 @@ static void walk_zones_in_node(struct seq_file *m, pg_data_t *pgdat,
432 spin_unlock_irqrestore(&zone->lock, flags); 512 spin_unlock_irqrestore(&zone->lock, flags);
433 } 513 }
434} 514}
515#endif
435 516
517#ifdef CONFIG_PROC_FS
436static void frag_show_print(struct seq_file *m, pg_data_t *pgdat, 518static void frag_show_print(struct seq_file *m, pg_data_t *pgdat,
437 struct zone *zone) 519 struct zone *zone)
438{ 520{
@@ -693,6 +775,16 @@ static const char * const vmstat_text[] = {
693 "allocstall", 775 "allocstall",
694 776
695 "pgrotated", 777 "pgrotated",
778
779#ifdef CONFIG_COMPACTION
780 "compact_blocks_moved",
781 "compact_pages_moved",
782 "compact_pagemigrate_failed",
783 "compact_stall",
784 "compact_fail",
785 "compact_success",
786#endif
787
696#ifdef CONFIG_HUGETLB_PAGE 788#ifdef CONFIG_HUGETLB_PAGE
697 "htlb_buddy_alloc_success", 789 "htlb_buddy_alloc_success",
698 "htlb_buddy_alloc_fail", 790 "htlb_buddy_alloc_fail",
@@ -954,3 +1046,162 @@ static int __init setup_vmstat(void)
954 return 0; 1046 return 0;
955} 1047}
956module_init(setup_vmstat) 1048module_init(setup_vmstat)
1049
1050#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_COMPACTION)
1051#include <linux/debugfs.h>
1052
1053static struct dentry *extfrag_debug_root;
1054
1055/*
1056 * Return an index indicating how much of the available free memory is
1057 * unusable for an allocation of the requested size.
1058 */
1059static int unusable_free_index(unsigned int order,
1060 struct contig_page_info *info)
1061{
1062 /* No free memory is interpreted as all free memory is unusable */
1063 if (info->free_pages == 0)
1064 return 1000;
1065
1066 /*
1067 * Index should be a value between 0 and 1. Return a value to 3
1068 * decimal places.
1069 *
1070 * 0 => no fragmentation
1071 * 1 => high fragmentation
1072 */
1073 return div_u64((info->free_pages - (info->free_blocks_suitable << order)) * 1000ULL, info->free_pages);
1074
1075}
1076
1077static void unusable_show_print(struct seq_file *m,
1078 pg_data_t *pgdat, struct zone *zone)
1079{
1080 unsigned int order;
1081 int index;
1082 struct contig_page_info info;
1083
1084 seq_printf(m, "Node %d, zone %8s ",
1085 pgdat->node_id,
1086 zone->name);
1087 for (order = 0; order < MAX_ORDER; ++order) {
1088 fill_contig_page_info(zone, order, &info);
1089 index = unusable_free_index(order, &info);
1090 seq_printf(m, "%d.%03d ", index / 1000, index % 1000);
1091 }
1092
1093 seq_putc(m, '\n');
1094}
1095
1096/*
1097 * Display unusable free space index
1098 *
1099 * The unusable free space index measures how much of the available free
1100 * memory cannot be used to satisfy an allocation of a given size and is a
1101 * value between 0 and 1. The higher the value, the more of free memory is
1102 * unusable and by implication, the worse the external fragmentation is. This
1103 * can be expressed as a percentage by multiplying by 100.
1104 */
1105static int unusable_show(struct seq_file *m, void *arg)
1106{
1107 pg_data_t *pgdat = (pg_data_t *)arg;
1108
1109 /* check memoryless node */
1110 if (!node_state(pgdat->node_id, N_HIGH_MEMORY))
1111 return 0;
1112
1113 walk_zones_in_node(m, pgdat, unusable_show_print);
1114
1115 return 0;
1116}
1117
1118static const struct seq_operations unusable_op = {
1119 .start = frag_start,
1120 .next = frag_next,
1121 .stop = frag_stop,
1122 .show = unusable_show,
1123};
1124
1125static int unusable_open(struct inode *inode, struct file *file)
1126{
1127 return seq_open(file, &unusable_op);
1128}
1129
1130static const struct file_operations unusable_file_ops = {
1131 .open = unusable_open,
1132 .read = seq_read,
1133 .llseek = seq_lseek,
1134 .release = seq_release,
1135};
1136
1137static void extfrag_show_print(struct seq_file *m,
1138 pg_data_t *pgdat, struct zone *zone)
1139{
1140 unsigned int order;
1141 int index;
1142
1143 /* Alloc on stack as interrupts are disabled for zone walk */
1144 struct contig_page_info info;
1145
1146 seq_printf(m, "Node %d, zone %8s ",
1147 pgdat->node_id,
1148 zone->name);
1149 for (order = 0; order < MAX_ORDER; ++order) {
1150 fill_contig_page_info(zone, order, &info);
1151 index = __fragmentation_index(order, &info);
1152 seq_printf(m, "%d.%03d ", index / 1000, index % 1000);
1153 }
1154
1155 seq_putc(m, '\n');
1156}
1157
1158/*
1159 * Display fragmentation index for orders that allocations would fail for
1160 */
1161static int extfrag_show(struct seq_file *m, void *arg)
1162{
1163 pg_data_t *pgdat = (pg_data_t *)arg;
1164
1165 walk_zones_in_node(m, pgdat, extfrag_show_print);
1166
1167 return 0;
1168}
1169
1170static const struct seq_operations extfrag_op = {
1171 .start = frag_start,
1172 .next = frag_next,
1173 .stop = frag_stop,
1174 .show = extfrag_show,
1175};
1176
1177static int extfrag_open(struct inode *inode, struct file *file)
1178{
1179 return seq_open(file, &extfrag_op);
1180}
1181
1182static const struct file_operations extfrag_file_ops = {
1183 .open = extfrag_open,
1184 .read = seq_read,
1185 .llseek = seq_lseek,
1186 .release = seq_release,
1187};
1188
1189static int __init extfrag_debug_init(void)
1190{
1191 extfrag_debug_root = debugfs_create_dir("extfrag", NULL);
1192 if (!extfrag_debug_root)
1193 return -ENOMEM;
1194
1195 if (!debugfs_create_file("unusable_index", 0444,
1196 extfrag_debug_root, NULL, &unusable_file_ops))
1197 return -ENOMEM;
1198
1199 if (!debugfs_create_file("extfrag_index", 0444,
1200 extfrag_debug_root, NULL, &extfrag_file_ops))
1201 return -ENOMEM;
1202
1203 return 0;
1204}
1205
1206module_init(extfrag_debug_init);
1207#endif