diff options
| author | Ingo Molnar <mingo@elte.hu> | 2010-02-26 03:20:17 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2010-02-26 03:20:17 -0500 |
| commit | 281b3714e91162b66add1cfac404cf7b81e3e2f2 (patch) | |
| tree | 9f80453153db272c207129d971e17d31a6bb214a /arch/x86 | |
| parent | 64b9fb5704a479d98a59f2a1d45d3331a8f847f8 (diff) | |
| parent | 7b60997f73865b019e595720185c85285ca3df9a (diff) | |
Merge branch 'tip/tracing/core' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace into tracing/core
Diffstat (limited to 'arch/x86')
| -rw-r--r-- | arch/x86/kernel/ftrace.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 309689245431..605ef196fdd6 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c | |||
| @@ -30,14 +30,32 @@ | |||
| 30 | 30 | ||
| 31 | #ifdef CONFIG_DYNAMIC_FTRACE | 31 | #ifdef CONFIG_DYNAMIC_FTRACE |
| 32 | 32 | ||
| 33 | /* | ||
| 34 | * modifying_code is set to notify NMIs that they need to use | ||
| 35 | * memory barriers when entering or exiting. But we don't want | ||
| 36 | * to burden NMIs with unnecessary memory barriers when code | ||
| 37 | * modification is not being done (which is most of the time). | ||
| 38 | * | ||
| 39 | * A mutex is already held when ftrace_arch_code_modify_prepare | ||
| 40 | * and post_process are called. No locks need to be taken here. | ||
| 41 | * | ||
| 42 | * Stop machine will make sure currently running NMIs are done | ||
| 43 | * and new NMIs will see the updated variable before we need | ||
| 44 | * to worry about NMIs doing memory barriers. | ||
| 45 | */ | ||
| 46 | static int modifying_code __read_mostly; | ||
| 47 | static DEFINE_PER_CPU(int, save_modifying_code); | ||
| 48 | |||
| 33 | int ftrace_arch_code_modify_prepare(void) | 49 | int ftrace_arch_code_modify_prepare(void) |
| 34 | { | 50 | { |
| 35 | set_kernel_text_rw(); | 51 | set_kernel_text_rw(); |
| 52 | modifying_code = 1; | ||
| 36 | return 0; | 53 | return 0; |
| 37 | } | 54 | } |
| 38 | 55 | ||
| 39 | int ftrace_arch_code_modify_post_process(void) | 56 | int ftrace_arch_code_modify_post_process(void) |
| 40 | { | 57 | { |
| 58 | modifying_code = 0; | ||
| 41 | set_kernel_text_ro(); | 59 | set_kernel_text_ro(); |
| 42 | return 0; | 60 | return 0; |
| 43 | } | 61 | } |
| @@ -149,6 +167,11 @@ static void ftrace_mod_code(void) | |||
| 149 | 167 | ||
| 150 | void ftrace_nmi_enter(void) | 168 | void ftrace_nmi_enter(void) |
| 151 | { | 169 | { |
| 170 | __get_cpu_var(save_modifying_code) = modifying_code; | ||
| 171 | |||
| 172 | if (!__get_cpu_var(save_modifying_code)) | ||
| 173 | return; | ||
| 174 | |||
| 152 | if (atomic_inc_return(&nmi_running) & MOD_CODE_WRITE_FLAG) { | 175 | if (atomic_inc_return(&nmi_running) & MOD_CODE_WRITE_FLAG) { |
| 153 | smp_rmb(); | 176 | smp_rmb(); |
| 154 | ftrace_mod_code(); | 177 | ftrace_mod_code(); |
| @@ -160,6 +183,9 @@ void ftrace_nmi_enter(void) | |||
| 160 | 183 | ||
| 161 | void ftrace_nmi_exit(void) | 184 | void ftrace_nmi_exit(void) |
| 162 | { | 185 | { |
| 186 | if (!__get_cpu_var(save_modifying_code)) | ||
| 187 | return; | ||
| 188 | |||
| 163 | /* Finish all executions before clearing nmi_running */ | 189 | /* Finish all executions before clearing nmi_running */ |
| 164 | smp_mb(); | 190 | smp_mb(); |
| 165 | atomic_dec(&nmi_running); | 191 | atomic_dec(&nmi_running); |
