Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'trace-v5.2-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace

Pull tracing fixes from Steven Rostedt:
"This includes three fixes:

- Fix a deadlock from a previous fix to keep module loading and
function tracing text modifications from stepping on each other
(this has a few patches to help document the issue in comments)

- Fix a crash when the snapshot buffer gets out of sync with the main
ring buffer

- Fix a memory leak when reading the memory logs"

* tag 'trace-v5.2-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace:
ftrace/x86: Anotate text_mutex split between ftrace_arch_code_modify_post_process() and ftrace_arch_code_modify_prepare()
tracing/snapshot: Resize spare buffer if size changed
tracing: Fix memory leak in tracing_err_log_open()
ftrace/x86: Add a comment to why we take text_mutex in ftrace_arch_code_modify_prepare()
ftrace/x86: Remove possible deadlock between register_kprobe() and ftrace_run_update_code()

+30 -14
+10
arch/x86/kernel/ftrace.c
··· 22 22 #include <linux/init.h> 23 23 #include <linux/list.h> 24 24 #include <linux/module.h> 25 + #include <linux/memory.h> 25 26 26 27 #include <trace/syscall.h> 27 28 ··· 35 34 #ifdef CONFIG_DYNAMIC_FTRACE 36 35 37 36 int ftrace_arch_code_modify_prepare(void) 37 + __acquires(&text_mutex) 38 38 { 39 + /* 40 + * Need to grab text_mutex to prevent a race from module loading 41 + * and live kernel patching from changing the text permissions while 42 + * ftrace has it set to "read/write". 43 + */ 44 + mutex_lock(&text_mutex); 39 45 set_kernel_text_rw(); 40 46 set_all_modules_text_rw(); 41 47 return 0; 42 48 } 43 49 44 50 int ftrace_arch_code_modify_post_process(void) 51 + __releases(&text_mutex) 45 52 { 46 53 set_all_modules_text_ro(); 47 54 set_kernel_text_ro(); 55 + mutex_unlock(&text_mutex); 48 56 return 0; 49 57 } 50 58
+1 -9
kernel/trace/ftrace.c
··· 34 34 #include <linux/hash.h> 35 35 #include <linux/rcupdate.h> 36 36 #include <linux/kprobes.h> 37 - #include <linux/memory.h> 38 37 39 38 #include <trace/events/sched.h> 40 39 ··· 2610 2611 { 2611 2612 int ret; 2612 2613 2613 - mutex_lock(&text_mutex); 2614 - 2615 2614 ret = ftrace_arch_code_modify_prepare(); 2616 2615 FTRACE_WARN_ON(ret); 2617 2616 if (ret) 2618 - goto out_unlock; 2617 + return; 2619 2618 2620 2619 /* 2621 2620 * By default we use stop_machine() to modify the code. ··· 2625 2628 2626 2629 ret = ftrace_arch_code_modify_post_process(); 2627 2630 FTRACE_WARN_ON(ret); 2628 - 2629 - out_unlock: 2630 - mutex_unlock(&text_mutex); 2631 2631 } 2632 2632 2633 2633 static void ftrace_run_modify_code(struct ftrace_ops *ops, int command, ··· 5778 5784 struct ftrace_page *pg; 5779 5785 5780 5786 mutex_lock(&ftrace_lock); 5781 - mutex_lock(&text_mutex); 5782 5787 5783 5788 if (ftrace_disabled) 5784 5789 goto out_unlock; ··· 5839 5846 ftrace_arch_code_modify_post_process(); 5840 5847 5841 5848 out_unlock: 5842 - mutex_unlock(&text_mutex); 5843 5849 mutex_unlock(&ftrace_lock); 5844 5850 5845 5851 process_cached_mods(mod->name);
+19 -5
kernel/trace/trace.c
··· 6719 6719 break; 6720 6720 } 6721 6721 #endif 6722 - if (!tr->allocated_snapshot) { 6722 + if (tr->allocated_snapshot) 6723 + ret = resize_buffer_duplicate_size(&tr->max_buffer, 6724 + &tr->trace_buffer, iter->cpu_file); 6725 + else 6723 6726 ret = tracing_alloc_snapshot_instance(tr); 6724 - if (ret < 0) 6725 - break; 6726 - } 6727 + if (ret < 0) 6728 + break; 6727 6729 local_irq_disable(); 6728 6730 /* Now, we're going to swap */ 6729 6731 if (iter->cpu_file == RING_BUFFER_ALL_CPUS) ··· 7128 7126 return count; 7129 7127 } 7130 7128 7129 + static int tracing_err_log_release(struct inode *inode, struct file *file) 7130 + { 7131 + struct trace_array *tr = inode->i_private; 7132 + 7133 + trace_array_put(tr); 7134 + 7135 + if (file->f_mode & FMODE_READ) 7136 + seq_release(inode, file); 7137 + 7138 + return 0; 7139 + } 7140 + 7131 7141 static const struct file_operations tracing_err_log_fops = { 7132 7142 .open = tracing_err_log_open, 7133 7143 .write = tracing_err_log_write, 7134 7144 .read = seq_read, 7135 7145 .llseek = seq_lseek, 7136 - .release = tracing_release_generic_tr, 7146 + .release = tracing_err_log_release, 7137 7147 }; 7138 7148 7139 7149 static int tracing_buffers_open(struct inode *inode, struct file *filp)