diff options
| -rw-r--r-- | include/linux/vm_event_item.h | 2 | ||||
| -rw-r--r-- | include/linux/vmstat.h | 11 | ||||
| -rw-r--r-- | include/trace/events/page_alloc.h | 71 | ||||
| -rw-r--r-- | mm/page_alloc.c | 20 | ||||
| -rw-r--r-- | mm/vmstat.c | 11 |
5 files changed, 105 insertions, 10 deletions
diff --git a/include/linux/vm_event_item.h b/include/linux/vm_event_item.h index 9e15a088ba38e2..a26e790cd48570 100644 --- a/include/linux/vm_event_item.h +++ b/include/linux/vm_event_item.h @@ -76,7 +76,7 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT, #ifdef CONFIG_COMPACTION COMPACTMIGRATE_SCANNED, COMPACTFREE_SCANNED, COMPACTISOLATED, - COMPACTSTALL, COMPACTFAIL, COMPACTSUCCESS, + COMPACTSTALL, COMPACTFAIL, COMPACTSUCCESS, COMPACTSUCCESS_EXTFRAG, KCOMPACTD_WAKE, KCOMPACTD_MIGRATE_SCANNED, KCOMPACTD_FREE_SCANNED, #endif diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index c287998908bf5f..e6560ed8795325 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h @@ -269,6 +269,17 @@ static inline void fold_vm_numa_events(void) } #endif /* CONFIG_NUMA */ +#ifdef CONFIG_COMPACTION +struct contig_page_info { + unsigned long free_pages; + unsigned long free_blocks_total; + unsigned long free_blocks_suitable; +}; +void fill_contig_page_info(struct zone *zone, unsigned int suitable_order,struct contig_page_info *info); +int __fragmentation_index(unsigned int order, struct contig_page_info *info); + +#endif /*CONFIG_COMPACTION*/ + #ifdef CONFIG_SMP void __mod_zone_page_state(struct zone *, enum zone_stat_item item, long); void __inc_zone_page_state(struct page *, enum zone_stat_item); diff --git a/include/trace/events/page_alloc.h b/include/trace/events/page_alloc.h new file mode 100644 index 00000000000000..f9125c1a944236 --- /dev/null +++ b/include/trace/events/page_alloc.h @@ -0,0 +1,71 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM page_alloc + +#if !defined(_TRACE_PAGE_ALLOC_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_PAGE_ALLOC_H +/* +#include <linux/types.h> +#include <linux/list.h> +*/ +#include <linux/tracepoint.h> + + + +#ifdef CONFIG_COMPACTION +TRACE_EVENT(mm_compaction_success, + TP_PROTO( + struct zone *zone, + unsigned int order, + int ret), + + TP_ARGS(zone, order, ret), + + TP_STRUCT__entry( + __field(int, nid) + __field(enum zone_type, idx) + __field(unsigned int, order) + __field(int, ret) + ), + + TP_fast_assign( + __entry->nid = zone_to_nid(zone); + __entry->idx = zone_idx(zone); + __entry->order = order; + __entry->ret = ret; + ), + + TP_printk("node=%d zone=%-8s order=%u, res_index=%d", + __entry->nid, + __print_symbolic(__entry->idx, ZONE_TYPE), + __entry->order, + __entry->ret + ) +); + +TRACE_EVENT(mm_compaction_failure, + TP_PROTO( + unsigned int order), + + TP_ARGS( order), + + TP_STRUCT__entry( + __field(unsigned int, order) + ), + + TP_fast_assign( + __entry->order = order; + ), + + TP_printk("order=%u", + __entry->order + ) +); + + + +#endif /* CONFIG_COMPACTION */ + +#endif /* _TRACE_PAGEALLOC_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h> diff --git a/mm/page_alloc.c b/mm/page_alloc.c index d1d037f97c5fc7..17ea91febacf3a 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -56,10 +56,17 @@ #include <linux/cacheinfo.h> #include <linux/pgalloc_tag.h> #include <asm/div64.h> +#include <linux/vmstat.h> +#include <linux/debugfs.h> +#include <linux/cpumask.h> #include "internal.h" #include "shuffle.h" #include "page_reporting.h" +#if defined CONFIG_COMPACTION +#define CREATE_TRACE_POINTS +#include <trace/events/page_alloc.h> +#endif /* Free Page Internal flags: for internal, non-pcp variants of free_pages(). */ typedef int __bitwise fpi_t; @@ -4088,10 +4095,20 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, if (page) { struct zone *zone = page_zone(page); - zone->compact_blockskip_flush = false; compaction_defer_reset(zone, order, true); + + struct contig_page_info info; + int res_index; + + fill_contig_page_info(zone, order, &info); + res_index = __fragmentation_index(order, &info); + count_vm_event(COMPACTSUCCESS); + trace_mm_compaction_success(zone, order, res_index); /* success trace point captured */ + if (res_index > 0 && res_index <= 1000) { + count_vm_event(COMPACTSUCCESS_EXTFRAG); + } return page; } @@ -4100,6 +4117,7 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, * is that pages exist, but not enough to satisfy watermarks. */ count_vm_event(COMPACTFAIL); + trace_mm_compaction_failure(order); /*failure trace point captured */ cond_resched(); diff --git a/mm/vmstat.c b/mm/vmstat.c index 71cd1ceba191e1..ce82ddb5afccf4 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c @@ -1056,12 +1056,6 @@ void memmap_pages_add(long delta) #ifdef CONFIG_COMPACTION -struct contig_page_info { - unsigned long free_pages; - unsigned long free_blocks_total; - unsigned long free_blocks_suitable; -}; - /* * Calculate the number of free pages in a zone, how many contiguous * pages are free and how many are large enough to satisfy an allocation of @@ -1070,7 +1064,7 @@ struct contig_page_info { * migrated. Calculating that is possible, but expensive and can be * figured out from userspace */ -static void fill_contig_page_info(struct zone *zone, +void fill_contig_page_info(struct zone *zone, unsigned int suitable_order, struct contig_page_info *info) { @@ -1109,7 +1103,7 @@ static void fill_contig_page_info(struct zone *zone, * The value can be used to determine if page reclaim or compaction * should be used */ -static int __fragmentation_index(unsigned int order, struct contig_page_info *info) +int __fragmentation_index(unsigned int order, struct contig_page_info *info) { unsigned long requested = 1UL << order; @@ -1380,6 +1374,7 @@ const char * const vmstat_text[] = { [I(COMPACTSTALL)] = "compact_stall", [I(COMPACTFAIL)] = "compact_fail", [I(COMPACTSUCCESS)] = "compact_success", + [I(COMPACTSUCCESS_EXTFRAG)] = "compact_success_extfrag", [I(KCOMPACTD_WAKE)] = "compact_daemon_wake", [I(KCOMPACTD_MIGRATE_SCANNED)] = "compact_daemon_migrate_scanned", [I(KCOMPACTD_FREE_SCANNED)] = "compact_daemon_free_scanned", |
