aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/vm_event_item.h2
-rw-r--r--include/linux/vmstat.h11
-rw-r--r--include/trace/events/page_alloc.h71
-rw-r--r--mm/page_alloc.c20
-rw-r--r--mm/vmstat.c11
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",