Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 198244
b: refs/heads/master
c: f1a5ab1
h: refs/heads/master
v: v3
  • Loading branch information
Mel Gorman authored and Linus Torvalds committed May 25, 2010
1 parent 222b03c commit e45b196
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d7a5752c0c19750312efab3a2a80d350e11fa4a2
refs/heads/master: f1a5ab1210579e2d3ac8c0c227645823af5aafb0
84 changes: 84 additions & 0 deletions trunk/mm/vmstat.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <linux/cpu.h>
#include <linux/vmstat.h>
#include <linux/sched.h>
#include <linux/math64.h>

#ifdef CONFIG_VM_EVENT_COUNTERS
DEFINE_PER_CPU(struct vm_event_state, vm_event_states) = {{0}};
Expand Down Expand Up @@ -420,6 +421,33 @@ static void fill_contig_page_info(struct zone *zone,
(order - suitable_order);
}
}

/*
* A fragmentation index only makes sense if an allocation of a requested
* size would fail. If that is true, the fragmentation index indicates
* whether external fragmentation or a lack of memory was the problem.
* The value can be used to determine if page reclaim or compaction
* should be used
*/
int fragmentation_index(unsigned int order, struct contig_page_info *info)
{
unsigned long requested = 1UL << order;

if (!info->free_blocks_total)
return 0;

/* Fragmentation index only makes sense when a request would fail */
if (info->free_blocks_suitable)
return -1000;

/*
* Index is between 0 and 1 so return within 3 decimal places
*
* 0 => allocation would fail due to lack of memory
* 1 => allocation would fail due to fragmentation
*/
return 1000 - div_u64( (1000+(div_u64(info->free_pages * 1000ULL, requested))), info->free_blocks_total);
}
#endif

#if defined(CONFIG_PROC_FS) || defined(CONFIG_COMPACTION)
Expand Down Expand Up @@ -1087,6 +1115,58 @@ static const struct file_operations unusable_file_ops = {
.release = seq_release,
};

static void extfrag_show_print(struct seq_file *m,
pg_data_t *pgdat, struct zone *zone)
{
unsigned int order;
int index;

/* Alloc on stack as interrupts are disabled for zone walk */
struct contig_page_info info;

seq_printf(m, "Node %d, zone %8s ",
pgdat->node_id,
zone->name);
for (order = 0; order < MAX_ORDER; ++order) {
fill_contig_page_info(zone, order, &info);
index = fragmentation_index(order, &info);
seq_printf(m, "%d.%03d ", index / 1000, index % 1000);
}

seq_putc(m, '\n');
}

/*
* Display fragmentation index for orders that allocations would fail for
*/
static int extfrag_show(struct seq_file *m, void *arg)
{
pg_data_t *pgdat = (pg_data_t *)arg;

walk_zones_in_node(m, pgdat, extfrag_show_print);

return 0;
}

static const struct seq_operations extfrag_op = {
.start = frag_start,
.next = frag_next,
.stop = frag_stop,
.show = extfrag_show,
};

static int extfrag_open(struct inode *inode, struct file *file)
{
return seq_open(file, &extfrag_op);
}

static const struct file_operations extfrag_file_ops = {
.open = extfrag_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};

static int __init extfrag_debug_init(void)
{
extfrag_debug_root = debugfs_create_dir("extfrag", NULL);
Expand All @@ -1097,6 +1177,10 @@ static int __init extfrag_debug_init(void)
extfrag_debug_root, NULL, &unusable_file_ops))
return -ENOMEM;

if (!debugfs_create_file("extfrag_index", 0444,
extfrag_debug_root, NULL, &extfrag_file_ops))
return -ENOMEM;

return 0;
}

Expand Down

0 comments on commit e45b196

Please sign in to comment.