diff options
author | Mel Gorman <mgorman@suse.de> | 2012-10-19 09:07:31 -0400 |
---|---|---|
committer | Mel Gorman <mgorman@suse.de> | 2012-12-11 09:28:35 -0500 |
commit | 7b2a2d4a18fffac3c4872021529b0657896db788 (patch) | |
tree | a0f05be191f12711a774368f6feb15bcd2eebf1a | |
parent | 5647bc293ab15f66a7b1cda850c5e9d162a6c7c2 (diff) |
mm: migrate: Add a tracepoint for migrate_pages
The pgmigrate_success and pgmigrate_fail vmstat counters tells the user
about migration activity but not the type or the reason. This patch adds
a tracepoint to identify the type of page migration and why the page is
being migrated.
Signed-off-by: Mel Gorman <mgorman@suse.de>
Reviewed-by: Rik van Riel <riel@redhat.com>
-rw-r--r-- | include/linux/migrate.h | 13 | ||||
-rw-r--r-- | include/trace/events/migrate.h | 51 | ||||
-rw-r--r-- | mm/compaction.c | 3 | ||||
-rw-r--r-- | mm/memory-failure.c | 3 | ||||
-rw-r--r-- | mm/memory_hotplug.c | 3 | ||||
-rw-r--r-- | mm/mempolicy.c | 6 | ||||
-rw-r--r-- | mm/migrate.c | 10 | ||||
-rw-r--r-- | mm/page_alloc.c | 3 |
8 files changed, 82 insertions, 10 deletions
diff --git a/include/linux/migrate.h b/include/linux/migrate.h index ce7e6671968b..9d1c159e2427 100644 --- a/include/linux/migrate.h +++ b/include/linux/migrate.h | |||
@@ -7,6 +7,15 @@ | |||
7 | 7 | ||
8 | typedef struct page *new_page_t(struct page *, unsigned long private, int **); | 8 | typedef struct page *new_page_t(struct page *, unsigned long private, int **); |
9 | 9 | ||
10 | enum migrate_reason { | ||
11 | MR_COMPACTION, | ||
12 | MR_MEMORY_FAILURE, | ||
13 | MR_MEMORY_HOTPLUG, | ||
14 | MR_SYSCALL, /* also applies to cpusets */ | ||
15 | MR_MEMPOLICY_MBIND, | ||
16 | MR_CMA | ||
17 | }; | ||
18 | |||
10 | #ifdef CONFIG_MIGRATION | 19 | #ifdef CONFIG_MIGRATION |
11 | 20 | ||
12 | extern void putback_lru_pages(struct list_head *l); | 21 | extern void putback_lru_pages(struct list_head *l); |
@@ -14,7 +23,7 @@ extern int migrate_page(struct address_space *, | |||
14 | struct page *, struct page *, enum migrate_mode); | 23 | struct page *, struct page *, enum migrate_mode); |
15 | extern int migrate_pages(struct list_head *l, new_page_t x, | 24 | extern int migrate_pages(struct list_head *l, new_page_t x, |
16 | unsigned long private, bool offlining, | 25 | unsigned long private, bool offlining, |
17 | enum migrate_mode mode); | 26 | enum migrate_mode mode, int reason); |
18 | extern int migrate_huge_page(struct page *, new_page_t x, | 27 | extern int migrate_huge_page(struct page *, new_page_t x, |
19 | unsigned long private, bool offlining, | 28 | unsigned long private, bool offlining, |
20 | enum migrate_mode mode); | 29 | enum migrate_mode mode); |
@@ -35,7 +44,7 @@ extern int migrate_huge_page_move_mapping(struct address_space *mapping, | |||
35 | static inline void putback_lru_pages(struct list_head *l) {} | 44 | static inline void putback_lru_pages(struct list_head *l) {} |
36 | static inline int migrate_pages(struct list_head *l, new_page_t x, | 45 | static inline int migrate_pages(struct list_head *l, new_page_t x, |
37 | unsigned long private, bool offlining, | 46 | unsigned long private, bool offlining, |
38 | enum migrate_mode mode) { return -ENOSYS; } | 47 | enum migrate_mode mode, int reason) { return -ENOSYS; } |
39 | static inline int migrate_huge_page(struct page *page, new_page_t x, | 48 | static inline int migrate_huge_page(struct page *page, new_page_t x, |
40 | unsigned long private, bool offlining, | 49 | unsigned long private, bool offlining, |
41 | enum migrate_mode mode) { return -ENOSYS; } | 50 | enum migrate_mode mode) { return -ENOSYS; } |
diff --git a/include/trace/events/migrate.h b/include/trace/events/migrate.h new file mode 100644 index 000000000000..ec2a6ccfd7e5 --- /dev/null +++ b/include/trace/events/migrate.h | |||
@@ -0,0 +1,51 @@ | |||
1 | #undef TRACE_SYSTEM | ||
2 | #define TRACE_SYSTEM migrate | ||
3 | |||
4 | #if !defined(_TRACE_MIGRATE_H) || defined(TRACE_HEADER_MULTI_READ) | ||
5 | #define _TRACE_MIGRATE_H | ||
6 | |||
7 | #define MIGRATE_MODE \ | ||
8 | {MIGRATE_ASYNC, "MIGRATE_ASYNC"}, \ | ||
9 | {MIGRATE_SYNC_LIGHT, "MIGRATE_SYNC_LIGHT"}, \ | ||
10 | {MIGRATE_SYNC, "MIGRATE_SYNC"} | ||
11 | |||
12 | #define MIGRATE_REASON \ | ||
13 | {MR_COMPACTION, "compaction"}, \ | ||
14 | {MR_MEMORY_FAILURE, "memory_failure"}, \ | ||
15 | {MR_MEMORY_HOTPLUG, "memory_hotplug"}, \ | ||
16 | {MR_SYSCALL, "syscall_or_cpuset"}, \ | ||
17 | {MR_MEMPOLICY_MBIND, "mempolicy_mbind"}, \ | ||
18 | {MR_CMA, "cma"} | ||
19 | |||
20 | TRACE_EVENT(mm_migrate_pages, | ||
21 | |||
22 | TP_PROTO(unsigned long succeeded, unsigned long failed, | ||
23 | enum migrate_mode mode, int reason), | ||
24 | |||
25 | TP_ARGS(succeeded, failed, mode, reason), | ||
26 | |||
27 | TP_STRUCT__entry( | ||
28 | __field( unsigned long, succeeded) | ||
29 | __field( unsigned long, failed) | ||
30 | __field( enum migrate_mode, mode) | ||
31 | __field( int, reason) | ||
32 | ), | ||
33 | |||
34 | TP_fast_assign( | ||
35 | __entry->succeeded = succeeded; | ||
36 | __entry->failed = failed; | ||
37 | __entry->mode = mode; | ||
38 | __entry->reason = reason; | ||
39 | ), | ||
40 | |||
41 | TP_printk("nr_succeeded=%lu nr_failed=%lu mode=%s reason=%s", | ||
42 | __entry->succeeded, | ||
43 | __entry->failed, | ||
44 | __print_symbolic(__entry->mode, MIGRATE_MODE), | ||
45 | __print_symbolic(__entry->reason, MIGRATE_REASON)) | ||
46 | ); | ||
47 | |||
48 | #endif /* _TRACE_MIGRATE_H */ | ||
49 | |||
50 | /* This part must be outside protection */ | ||
51 | #include <trace/define_trace.h> | ||
diff --git a/mm/compaction.c b/mm/compaction.c index 00ad88395216..2c077a78487c 100644 --- a/mm/compaction.c +++ b/mm/compaction.c | |||
@@ -990,7 +990,8 @@ static int compact_zone(struct zone *zone, struct compact_control *cc) | |||
990 | nr_migrate = cc->nr_migratepages; | 990 | nr_migrate = cc->nr_migratepages; |
991 | err = migrate_pages(&cc->migratepages, compaction_alloc, | 991 | err = migrate_pages(&cc->migratepages, compaction_alloc, |
992 | (unsigned long)cc, false, | 992 | (unsigned long)cc, false, |
993 | cc->sync ? MIGRATE_SYNC_LIGHT : MIGRATE_ASYNC); | 993 | cc->sync ? MIGRATE_SYNC_LIGHT : MIGRATE_ASYNC, |
994 | MR_COMPACTION); | ||
994 | update_nr_listpages(cc); | 995 | update_nr_listpages(cc); |
995 | nr_remaining = cc->nr_migratepages; | 996 | nr_remaining = cc->nr_migratepages; |
996 | 997 | ||
diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 6c5899b9034a..ddb68a169e45 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c | |||
@@ -1558,7 +1558,8 @@ int soft_offline_page(struct page *page, int flags) | |||
1558 | page_is_file_cache(page)); | 1558 | page_is_file_cache(page)); |
1559 | list_add(&page->lru, &pagelist); | 1559 | list_add(&page->lru, &pagelist); |
1560 | ret = migrate_pages(&pagelist, new_page, MPOL_MF_MOVE_ALL, | 1560 | ret = migrate_pages(&pagelist, new_page, MPOL_MF_MOVE_ALL, |
1561 | false, MIGRATE_SYNC); | 1561 | false, MIGRATE_SYNC, |
1562 | MR_MEMORY_FAILURE); | ||
1562 | if (ret) { | 1563 | if (ret) { |
1563 | putback_lru_pages(&pagelist); | 1564 | putback_lru_pages(&pagelist); |
1564 | pr_info("soft offline: %#lx: migration failed %d, type %lx\n", | 1565 | pr_info("soft offline: %#lx: migration failed %d, type %lx\n", |
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index e4eeacae2b91..e598bd15c041 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c | |||
@@ -812,7 +812,8 @@ do_migrate_range(unsigned long start_pfn, unsigned long end_pfn) | |||
812 | * migrate_pages returns # of failed pages. | 812 | * migrate_pages returns # of failed pages. |
813 | */ | 813 | */ |
814 | ret = migrate_pages(&source, alloc_migrate_target, 0, | 814 | ret = migrate_pages(&source, alloc_migrate_target, 0, |
815 | true, MIGRATE_SYNC); | 815 | true, MIGRATE_SYNC, |
816 | MR_MEMORY_HOTPLUG); | ||
816 | if (ret) | 817 | if (ret) |
817 | putback_lru_pages(&source); | 818 | putback_lru_pages(&source); |
818 | } | 819 | } |
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index d04a8a54c294..66e90ecc2350 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c | |||
@@ -961,7 +961,8 @@ static int migrate_to_node(struct mm_struct *mm, int source, int dest, | |||
961 | 961 | ||
962 | if (!list_empty(&pagelist)) { | 962 | if (!list_empty(&pagelist)) { |
963 | err = migrate_pages(&pagelist, new_node_page, dest, | 963 | err = migrate_pages(&pagelist, new_node_page, dest, |
964 | false, MIGRATE_SYNC); | 964 | false, MIGRATE_SYNC, |
965 | MR_SYSCALL); | ||
965 | if (err) | 966 | if (err) |
966 | putback_lru_pages(&pagelist); | 967 | putback_lru_pages(&pagelist); |
967 | } | 968 | } |
@@ -1202,7 +1203,8 @@ static long do_mbind(unsigned long start, unsigned long len, | |||
1202 | if (!list_empty(&pagelist)) { | 1203 | if (!list_empty(&pagelist)) { |
1203 | nr_failed = migrate_pages(&pagelist, new_vma_page, | 1204 | nr_failed = migrate_pages(&pagelist, new_vma_page, |
1204 | (unsigned long)vma, | 1205 | (unsigned long)vma, |
1205 | false, MIGRATE_SYNC); | 1206 | false, MIGRATE_SYNC, |
1207 | MR_MEMPOLICY_MBIND); | ||
1206 | if (nr_failed) | 1208 | if (nr_failed) |
1207 | putback_lru_pages(&pagelist); | 1209 | putback_lru_pages(&pagelist); |
1208 | } | 1210 | } |
diff --git a/mm/migrate.c b/mm/migrate.c index 04687f69cc17..27be9c923dc1 100644 --- a/mm/migrate.c +++ b/mm/migrate.c | |||
@@ -38,6 +38,9 @@ | |||
38 | 38 | ||
39 | #include <asm/tlbflush.h> | 39 | #include <asm/tlbflush.h> |
40 | 40 | ||
41 | #define CREATE_TRACE_POINTS | ||
42 | #include <trace/events/migrate.h> | ||
43 | |||
41 | #include "internal.h" | 44 | #include "internal.h" |
42 | 45 | ||
43 | /* | 46 | /* |
@@ -958,7 +961,7 @@ out: | |||
958 | */ | 961 | */ |
959 | int migrate_pages(struct list_head *from, | 962 | int migrate_pages(struct list_head *from, |
960 | new_page_t get_new_page, unsigned long private, bool offlining, | 963 | new_page_t get_new_page, unsigned long private, bool offlining, |
961 | enum migrate_mode mode) | 964 | enum migrate_mode mode, int reason) |
962 | { | 965 | { |
963 | int retry = 1; | 966 | int retry = 1; |
964 | int nr_failed = 0; | 967 | int nr_failed = 0; |
@@ -1004,6 +1007,8 @@ out: | |||
1004 | count_vm_events(PGMIGRATE_SUCCESS, nr_succeeded); | 1007 | count_vm_events(PGMIGRATE_SUCCESS, nr_succeeded); |
1005 | if (nr_failed) | 1008 | if (nr_failed) |
1006 | count_vm_events(PGMIGRATE_FAIL, nr_failed); | 1009 | count_vm_events(PGMIGRATE_FAIL, nr_failed); |
1010 | trace_mm_migrate_pages(nr_succeeded, nr_failed, mode, reason); | ||
1011 | |||
1007 | if (!swapwrite) | 1012 | if (!swapwrite) |
1008 | current->flags &= ~PF_SWAPWRITE; | 1013 | current->flags &= ~PF_SWAPWRITE; |
1009 | 1014 | ||
@@ -1145,7 +1150,8 @@ set_status: | |||
1145 | err = 0; | 1150 | err = 0; |
1146 | if (!list_empty(&pagelist)) { | 1151 | if (!list_empty(&pagelist)) { |
1147 | err = migrate_pages(&pagelist, new_page_node, | 1152 | err = migrate_pages(&pagelist, new_page_node, |
1148 | (unsigned long)pm, 0, MIGRATE_SYNC); | 1153 | (unsigned long)pm, 0, MIGRATE_SYNC, |
1154 | MR_SYSCALL); | ||
1149 | if (err) | 1155 | if (err) |
1150 | putback_lru_pages(&pagelist); | 1156 | putback_lru_pages(&pagelist); |
1151 | } | 1157 | } |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 7bb35ac0964a..5953dc2d196f 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -5707,7 +5707,8 @@ static int __alloc_contig_migrate_range(struct compact_control *cc, | |||
5707 | 5707 | ||
5708 | ret = migrate_pages(&cc->migratepages, | 5708 | ret = migrate_pages(&cc->migratepages, |
5709 | alloc_migrate_target, | 5709 | alloc_migrate_target, |
5710 | 0, false, MIGRATE_SYNC); | 5710 | 0, false, MIGRATE_SYNC, |
5711 | MR_CMA); | ||
5711 | } | 5712 | } |
5712 | 5713 | ||
5713 | putback_lru_pages(&cc->migratepages); | 5714 | putback_lru_pages(&cc->migratepages); |