diff options
-rw-r--r-- | arch/x86/kernel/ftrace.c | 26 | ||||
-rw-r--r-- | kernel/trace/trace.c | 31 |
2 files changed, 48 insertions, 9 deletions
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index fe5f859130b5..6685b0fc1b44 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c | |||
@@ -91,6 +91,19 @@ static int mod_code_write; | |||
91 | static void *mod_code_ip; | 91 | static void *mod_code_ip; |
92 | static void *mod_code_newcode; | 92 | static void *mod_code_newcode; |
93 | 93 | ||
94 | static int nmi_wait_count; | ||
95 | static atomic_t nmi_update_count; | ||
96 | |||
97 | int ftrace_arch_read_dyn_info(char *buf, int size) | ||
98 | { | ||
99 | int r; | ||
100 | |||
101 | r = snprintf(buf, size, "%u %u", | ||
102 | nmi_wait_count, | ||
103 | atomic_read(&nmi_update_count)); | ||
104 | return r; | ||
105 | } | ||
106 | |||
94 | static void ftrace_mod_code(void) | 107 | static void ftrace_mod_code(void) |
95 | { | 108 | { |
96 | /* | 109 | /* |
@@ -109,8 +122,10 @@ void ftrace_nmi_enter(void) | |||
109 | atomic_inc(&in_nmi); | 122 | atomic_inc(&in_nmi); |
110 | /* Must have in_nmi seen before reading write flag */ | 123 | /* Must have in_nmi seen before reading write flag */ |
111 | smp_mb(); | 124 | smp_mb(); |
112 | if (mod_code_write) | 125 | if (mod_code_write) { |
113 | ftrace_mod_code(); | 126 | ftrace_mod_code(); |
127 | atomic_inc(&nmi_update_count); | ||
128 | } | ||
114 | } | 129 | } |
115 | 130 | ||
116 | void ftrace_nmi_exit(void) | 131 | void ftrace_nmi_exit(void) |
@@ -122,8 +137,15 @@ void ftrace_nmi_exit(void) | |||
122 | 137 | ||
123 | static void wait_for_nmi(void) | 138 | static void wait_for_nmi(void) |
124 | { | 139 | { |
125 | while (atomic_read(&in_nmi)) | 140 | int waited = 0; |
141 | |||
142 | while (atomic_read(&in_nmi)) { | ||
143 | waited = 1; | ||
126 | cpu_relax(); | 144 | cpu_relax(); |
145 | } | ||
146 | |||
147 | if (waited) | ||
148 | nmi_wait_count++; | ||
127 | } | 149 | } |
128 | 150 | ||
129 | static int | 151 | static int |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index a610ca771558..bc36febc0771 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -2815,22 +2815,39 @@ static struct file_operations tracing_mark_fops = { | |||
2815 | 2815 | ||
2816 | #ifdef CONFIG_DYNAMIC_FTRACE | 2816 | #ifdef CONFIG_DYNAMIC_FTRACE |
2817 | 2817 | ||
2818 | #define DYN_INFO_BUF_SIZE 1023 | ||
2819 | static char ftrace_dyn_info_buffer[DYN_INFO_BUF_SIZE+1]; | ||
2820 | static DEFINE_MUTEX(dyn_info_mutex); | ||
2821 | |||
2822 | int __weak ftrace_arch_read_dyn_info(char *buf, int size) | ||
2823 | { | ||
2824 | return 0; | ||
2825 | } | ||
2826 | |||
2818 | static ssize_t | 2827 | static ssize_t |
2819 | tracing_read_long(struct file *filp, char __user *ubuf, | 2828 | tracing_read_dyn_info(struct file *filp, char __user *ubuf, |
2820 | size_t cnt, loff_t *ppos) | 2829 | size_t cnt, loff_t *ppos) |
2821 | { | 2830 | { |
2822 | unsigned long *p = filp->private_data; | 2831 | unsigned long *p = filp->private_data; |
2823 | char buf[64]; | 2832 | char *buf = ftrace_dyn_info_buffer; |
2824 | int r; | 2833 | int r; |
2825 | 2834 | ||
2826 | r = sprintf(buf, "%ld\n", *p); | 2835 | mutex_lock(&dyn_info_mutex); |
2836 | r = sprintf(buf, "%ld ", *p); | ||
2827 | 2837 | ||
2828 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); | 2838 | r += ftrace_arch_read_dyn_info(buf+r, DYN_INFO_BUF_SIZE-r); |
2839 | buf[r++] = '\n'; | ||
2840 | |||
2841 | r = simple_read_from_buffer(ubuf, cnt, ppos, buf, r); | ||
2842 | |||
2843 | mutex_unlock(&dyn_info_mutex); | ||
2844 | |||
2845 | return r; | ||
2829 | } | 2846 | } |
2830 | 2847 | ||
2831 | static struct file_operations tracing_read_long_fops = { | 2848 | static struct file_operations tracing_dyn_info_fops = { |
2832 | .open = tracing_open_generic, | 2849 | .open = tracing_open_generic, |
2833 | .read = tracing_read_long, | 2850 | .read = tracing_read_dyn_info, |
2834 | }; | 2851 | }; |
2835 | #endif | 2852 | #endif |
2836 | 2853 | ||
@@ -2939,7 +2956,7 @@ static __init int tracer_init_debugfs(void) | |||
2939 | #ifdef CONFIG_DYNAMIC_FTRACE | 2956 | #ifdef CONFIG_DYNAMIC_FTRACE |
2940 | entry = debugfs_create_file("dyn_ftrace_total_info", 0444, d_tracer, | 2957 | entry = debugfs_create_file("dyn_ftrace_total_info", 0444, d_tracer, |
2941 | &ftrace_update_tot_cnt, | 2958 | &ftrace_update_tot_cnt, |
2942 | &tracing_read_long_fops); | 2959 | &tracing_dyn_info_fops); |
2943 | if (!entry) | 2960 | if (!entry) |
2944 | pr_warning("Could not create debugfs " | 2961 | pr_warning("Could not create debugfs " |
2945 | "'dyn_ftrace_total_info' entry\n"); | 2962 | "'dyn_ftrace_total_info' entry\n"); |