diff options
-rw-r--r-- | include/linux/perf_counter.h | 3 | ||||
-rw-r--r-- | init/Kconfig | 5 | ||||
-rw-r--r-- | kernel/perf_counter.c | 43 |
3 files changed, 51 insertions, 0 deletions
diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 08c11a6afebc..065984c1ff57 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h | |||
@@ -53,6 +53,8 @@ enum hw_event_types { | |||
53 | PERF_COUNT_PAGE_FAULTS_MAJ = -7, | 53 | PERF_COUNT_PAGE_FAULTS_MAJ = -7, |
54 | 54 | ||
55 | PERF_SW_EVENTS_MIN = -8, | 55 | PERF_SW_EVENTS_MIN = -8, |
56 | |||
57 | PERF_TP_EVENTS_MIN = -65536 | ||
56 | }; | 58 | }; |
57 | 59 | ||
58 | /* | 60 | /* |
@@ -222,6 +224,7 @@ struct perf_counter { | |||
222 | struct perf_data *usrdata; | 224 | struct perf_data *usrdata; |
223 | struct perf_data data[2]; | 225 | struct perf_data data[2]; |
224 | 226 | ||
227 | void (*destroy)(struct perf_counter *); | ||
225 | struct rcu_head rcu_head; | 228 | struct rcu_head rcu_head; |
226 | #endif | 229 | #endif |
227 | }; | 230 | }; |
diff --git a/init/Kconfig b/init/Kconfig index 38a2ecd47c37..4f647142f2e6 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -947,6 +947,11 @@ config PERF_COUNTERS | |||
947 | 947 | ||
948 | Say Y if unsure. | 948 | Say Y if unsure. |
949 | 949 | ||
950 | config EVENT_PROFILE | ||
951 | bool "Tracepoint profile sources" | ||
952 | depends on PERF_COUNTERS && EVENT_TRACER | ||
953 | default y | ||
954 | |||
950 | endmenu | 955 | endmenu |
951 | 956 | ||
952 | config VM_EVENT_COUNTERS | 957 | config VM_EVENT_COUNTERS |
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 97f891ffeb40..0bbe3e45ba0d 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c | |||
@@ -1152,6 +1152,9 @@ static void free_counter_rcu(struct rcu_head *head) | |||
1152 | 1152 | ||
1153 | static void free_counter(struct perf_counter *counter) | 1153 | static void free_counter(struct perf_counter *counter) |
1154 | { | 1154 | { |
1155 | if (counter->destroy) | ||
1156 | counter->destroy(counter); | ||
1157 | |||
1155 | call_rcu(&counter->rcu_head, free_counter_rcu); | 1158 | call_rcu(&counter->rcu_head, free_counter_rcu); |
1156 | } | 1159 | } |
1157 | 1160 | ||
@@ -1727,6 +1730,45 @@ static const struct hw_perf_counter_ops perf_ops_cpu_migrations = { | |||
1727 | .read = cpu_migrations_perf_counter_read, | 1730 | .read = cpu_migrations_perf_counter_read, |
1728 | }; | 1731 | }; |
1729 | 1732 | ||
1733 | #ifdef CONFIG_EVENT_PROFILE | ||
1734 | void perf_tpcounter_event(int event_id) | ||
1735 | { | ||
1736 | perf_swcounter_event(PERF_TP_EVENTS_MIN + event_id, 1, 1, | ||
1737 | task_pt_regs(current)); | ||
1738 | } | ||
1739 | |||
1740 | extern int ftrace_profile_enable(int); | ||
1741 | extern void ftrace_profile_disable(int); | ||
1742 | |||
1743 | static void tp_perf_counter_destroy(struct perf_counter *counter) | ||
1744 | { | ||
1745 | int event_id = counter->hw_event.type - PERF_TP_EVENTS_MIN; | ||
1746 | |||
1747 | ftrace_profile_disable(event_id); | ||
1748 | } | ||
1749 | |||
1750 | static const struct hw_perf_counter_ops * | ||
1751 | tp_perf_counter_init(struct perf_counter *counter) | ||
1752 | { | ||
1753 | int event_id = counter->hw_event.type - PERF_TP_EVENTS_MIN; | ||
1754 | int ret; | ||
1755 | |||
1756 | ret = ftrace_profile_enable(event_id); | ||
1757 | if (ret) | ||
1758 | return NULL; | ||
1759 | |||
1760 | counter->destroy = tp_perf_counter_destroy; | ||
1761 | |||
1762 | return &perf_ops_generic; | ||
1763 | } | ||
1764 | #else | ||
1765 | static const struct hw_perf_counter_ops * | ||
1766 | tp_perf_counter_init(struct perf_counter *counter) | ||
1767 | { | ||
1768 | return NULL; | ||
1769 | } | ||
1770 | #endif | ||
1771 | |||
1730 | static const struct hw_perf_counter_ops * | 1772 | static const struct hw_perf_counter_ops * |
1731 | sw_perf_counter_init(struct perf_counter *counter) | 1773 | sw_perf_counter_init(struct perf_counter *counter) |
1732 | { | 1774 | { |
@@ -1772,6 +1814,7 @@ sw_perf_counter_init(struct perf_counter *counter) | |||
1772 | hw_ops = &perf_ops_cpu_migrations; | 1814 | hw_ops = &perf_ops_cpu_migrations; |
1773 | break; | 1815 | break; |
1774 | default: | 1816 | default: |
1817 | hw_ops = tp_perf_counter_init(counter); | ||
1775 | break; | 1818 | break; |
1776 | } | 1819 | } |
1777 | 1820 | ||