diff options
| -rw-r--r-- | include/trace/events/compaction.h | 74 | ||||
| -rw-r--r-- | mm/compaction.c | 14 |
2 files changed, 87 insertions, 1 deletions
diff --git a/include/trace/events/compaction.h b/include/trace/events/compaction.h new file mode 100644 index 000000000000..388bcdd26d46 --- /dev/null +++ b/include/trace/events/compaction.h | |||
| @@ -0,0 +1,74 @@ | |||
| 1 | #undef TRACE_SYSTEM | ||
| 2 | #define TRACE_SYSTEM compaction | ||
| 3 | |||
| 4 | #if !defined(_TRACE_COMPACTION_H) || defined(TRACE_HEADER_MULTI_READ) | ||
| 5 | #define _TRACE_COMPACTION_H | ||
| 6 | |||
| 7 | #include <linux/types.h> | ||
| 8 | #include <linux/tracepoint.h> | ||
| 9 | #include "gfpflags.h" | ||
| 10 | |||
| 11 | DECLARE_EVENT_CLASS(mm_compaction_isolate_template, | ||
| 12 | |||
| 13 | TP_PROTO(unsigned long nr_scanned, | ||
| 14 | unsigned long nr_taken), | ||
| 15 | |||
| 16 | TP_ARGS(nr_scanned, nr_taken), | ||
| 17 | |||
| 18 | TP_STRUCT__entry( | ||
| 19 | __field(unsigned long, nr_scanned) | ||
| 20 | __field(unsigned long, nr_taken) | ||
| 21 | ), | ||
| 22 | |||
| 23 | TP_fast_assign( | ||
| 24 | __entry->nr_scanned = nr_scanned; | ||
| 25 | __entry->nr_taken = nr_taken; | ||
| 26 | ), | ||
| 27 | |||
| 28 | TP_printk("nr_scanned=%lu nr_taken=%lu", | ||
| 29 | __entry->nr_scanned, | ||
| 30 | __entry->nr_taken) | ||
| 31 | ); | ||
| 32 | |||
| 33 | DEFINE_EVENT(mm_compaction_isolate_template, mm_compaction_isolate_migratepages, | ||
| 34 | |||
| 35 | TP_PROTO(unsigned long nr_scanned, | ||
| 36 | unsigned long nr_taken), | ||
| 37 | |||
| 38 | TP_ARGS(nr_scanned, nr_taken) | ||
| 39 | ); | ||
| 40 | |||
| 41 | DEFINE_EVENT(mm_compaction_isolate_template, mm_compaction_isolate_freepages, | ||
| 42 | TP_PROTO(unsigned long nr_scanned, | ||
| 43 | unsigned long nr_taken), | ||
| 44 | |||
| 45 | TP_ARGS(nr_scanned, nr_taken) | ||
| 46 | ); | ||
| 47 | |||
| 48 | TRACE_EVENT(mm_compaction_migratepages, | ||
| 49 | |||
| 50 | TP_PROTO(unsigned long nr_migrated, | ||
| 51 | unsigned long nr_failed), | ||
| 52 | |||
| 53 | TP_ARGS(nr_migrated, nr_failed), | ||
| 54 | |||
| 55 | TP_STRUCT__entry( | ||
| 56 | __field(unsigned long, nr_migrated) | ||
| 57 | __field(unsigned long, nr_failed) | ||
| 58 | ), | ||
| 59 | |||
| 60 | TP_fast_assign( | ||
| 61 | __entry->nr_migrated = nr_migrated; | ||
| 62 | __entry->nr_failed = nr_failed; | ||
| 63 | ), | ||
| 64 | |||
| 65 | TP_printk("nr_migrated=%lu nr_failed=%lu", | ||
| 66 | __entry->nr_migrated, | ||
| 67 | __entry->nr_failed) | ||
| 68 | ); | ||
| 69 | |||
| 70 | |||
| 71 | #endif /* _TRACE_COMPACTION_H */ | ||
| 72 | |||
| 73 | /* This part must be outside protection */ | ||
| 74 | #include <trace/define_trace.h> | ||
diff --git a/mm/compaction.c b/mm/compaction.c index 1a8894eadf72..20011a850fef 100644 --- a/mm/compaction.c +++ b/mm/compaction.c | |||
| @@ -16,6 +16,9 @@ | |||
| 16 | #include <linux/sysfs.h> | 16 | #include <linux/sysfs.h> |
| 17 | #include "internal.h" | 17 | #include "internal.h" |
| 18 | 18 | ||
| 19 | #define CREATE_TRACE_POINTS | ||
| 20 | #include <trace/events/compaction.h> | ||
| 21 | |||
| 19 | /* | 22 | /* |
| 20 | * compact_control is used to track pages being migrated and the free pages | 23 | * compact_control is used to track pages being migrated and the free pages |
| 21 | * they are being migrated to during memory compaction. The free_pfn starts | 24 | * they are being migrated to during memory compaction. The free_pfn starts |
| @@ -60,7 +63,7 @@ static unsigned long isolate_freepages_block(struct zone *zone, | |||
| 60 | struct list_head *freelist) | 63 | struct list_head *freelist) |
| 61 | { | 64 | { |
| 62 | unsigned long zone_end_pfn, end_pfn; | 65 | unsigned long zone_end_pfn, end_pfn; |
| 63 | int total_isolated = 0; | 66 | int nr_scanned = 0, total_isolated = 0; |
| 64 | struct page *cursor; | 67 | struct page *cursor; |
| 65 | 68 | ||
| 66 | /* Get the last PFN we should scan for free pages at */ | 69 | /* Get the last PFN we should scan for free pages at */ |
| @@ -81,6 +84,7 @@ static unsigned long isolate_freepages_block(struct zone *zone, | |||
| 81 | 84 | ||
| 82 | if (!pfn_valid_within(blockpfn)) | 85 | if (!pfn_valid_within(blockpfn)) |
| 83 | continue; | 86 | continue; |
| 87 | nr_scanned++; | ||
| 84 | 88 | ||
| 85 | if (!PageBuddy(page)) | 89 | if (!PageBuddy(page)) |
| 86 | continue; | 90 | continue; |
| @@ -100,6 +104,7 @@ static unsigned long isolate_freepages_block(struct zone *zone, | |||
| 100 | } | 104 | } |
| 101 | } | 105 | } |
| 102 | 106 | ||
| 107 | trace_mm_compaction_isolate_freepages(nr_scanned, total_isolated); | ||
| 103 | return total_isolated; | 108 | return total_isolated; |
| 104 | } | 109 | } |
| 105 | 110 | ||
| @@ -234,6 +239,7 @@ static unsigned long isolate_migratepages(struct zone *zone, | |||
| 234 | struct compact_control *cc) | 239 | struct compact_control *cc) |
| 235 | { | 240 | { |
| 236 | unsigned long low_pfn, end_pfn; | 241 | unsigned long low_pfn, end_pfn; |
| 242 | unsigned long nr_scanned = 0, nr_isolated = 0; | ||
| 237 | struct list_head *migratelist = &cc->migratepages; | 243 | struct list_head *migratelist = &cc->migratepages; |
| 238 | 244 | ||
| 239 | /* Do not scan outside zone boundaries */ | 245 | /* Do not scan outside zone boundaries */ |
| @@ -266,6 +272,7 @@ static unsigned long isolate_migratepages(struct zone *zone, | |||
| 266 | struct page *page; | 272 | struct page *page; |
| 267 | if (!pfn_valid_within(low_pfn)) | 273 | if (!pfn_valid_within(low_pfn)) |
| 268 | continue; | 274 | continue; |
| 275 | nr_scanned++; | ||
| 269 | 276 | ||
| 270 | /* Get the page and skip if free */ | 277 | /* Get the page and skip if free */ |
| 271 | page = pfn_to_page(low_pfn); | 278 | page = pfn_to_page(low_pfn); |
| @@ -280,6 +287,7 @@ static unsigned long isolate_migratepages(struct zone *zone, | |||
| 280 | del_page_from_lru_list(zone, page, page_lru(page)); | 287 | del_page_from_lru_list(zone, page, page_lru(page)); |
| 281 | list_add(&page->lru, migratelist); | 288 | list_add(&page->lru, migratelist); |
| 282 | cc->nr_migratepages++; | 289 | cc->nr_migratepages++; |
| 290 | nr_isolated++; | ||
| 283 | 291 | ||
| 284 | /* Avoid isolating too much */ | 292 | /* Avoid isolating too much */ |
| 285 | if (cc->nr_migratepages == COMPACT_CLUSTER_MAX) | 293 | if (cc->nr_migratepages == COMPACT_CLUSTER_MAX) |
| @@ -291,6 +299,8 @@ static unsigned long isolate_migratepages(struct zone *zone, | |||
| 291 | spin_unlock_irq(&zone->lru_lock); | 299 | spin_unlock_irq(&zone->lru_lock); |
| 292 | cc->migrate_pfn = low_pfn; | 300 | cc->migrate_pfn = low_pfn; |
| 293 | 301 | ||
| 302 | trace_mm_compaction_isolate_migratepages(nr_scanned, nr_isolated); | ||
| 303 | |||
| 294 | return cc->nr_migratepages; | 304 | return cc->nr_migratepages; |
| 295 | } | 305 | } |
| 296 | 306 | ||
| @@ -401,6 +411,8 @@ static int compact_zone(struct zone *zone, struct compact_control *cc) | |||
| 401 | count_vm_events(COMPACTPAGES, nr_migrate - nr_remaining); | 411 | count_vm_events(COMPACTPAGES, nr_migrate - nr_remaining); |
| 402 | if (nr_remaining) | 412 | if (nr_remaining) |
| 403 | count_vm_events(COMPACTPAGEFAILED, nr_remaining); | 413 | count_vm_events(COMPACTPAGEFAILED, nr_remaining); |
| 414 | trace_mm_compaction_migratepages(nr_migrate - nr_remaining, | ||
| 415 | nr_remaining); | ||
| 404 | 416 | ||
| 405 | /* Release LRU pages not migrated */ | 417 | /* Release LRU pages not migrated */ |
| 406 | if (!list_empty(&cc->migratepages)) { | 418 | if (!list_empty(&cc->migratepages)) { |
