From: Greg Kroah-Hartman Date: Sun, 4 Dec 2022 16:12:17 +0000 (+0100) Subject: drop queue-4.19/tracing-add-unified-dynamic-event-framework.patch X-Git-Tag: v4.9.335~39 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7ee430239b155b2fe488b18f405eea204c9e9f2e;p=thirdparty%2Fkernel%2Fstable-queue.git drop queue-4.19/tracing-add-unified-dynamic-event-framework.patch Not relevant for older kernels --- diff --git a/queue-4.19/series b/queue-4.19/series index 00160efd062..fa7656b9782 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -103,8 +103,6 @@ parisc-increase-size-of-gcc-stack-frame-check.patch xtensa-increase-size-of-gcc-stack-frame-check.patch parisc-increase-frame_warn-to-2048-bytes-on-parisc.patch kconfig.debug-provide-a-little-extra-frame_warn-leew.patch -tracing-add-unified-dynamic-event-framework.patch -tracing-free-buffers-when-a-used-dynamic-event-is-re.patch tcp-udp-fix-memory-leak-in-ipv6_renew_options.patch nvme-restrict-management-ioctls-to-admin.patch x86-tsx-add-a-feature-bit-for-tsx-control-msr-support.patch diff --git a/queue-4.19/tracing-add-unified-dynamic-event-framework.patch b/queue-4.19/tracing-add-unified-dynamic-event-framework.patch deleted file mode 100644 index 14e1272c455..00000000000 --- a/queue-4.19/tracing-add-unified-dynamic-event-framework.patch +++ /dev/null @@ -1,419 +0,0 @@ -From 58954e6bb1b1066e34c6678826c6155aa17ec01f Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 5 Nov 2018 18:02:08 +0900 -Subject: tracing: Add unified dynamic event framework - -From: Masami Hiramatsu - -[ Upstream commit 5448d44c38557fc15d1c53b608a9c9f0e1ca8f86 ] - -Add unified dynamic event framework for ftrace kprobes, uprobes -and synthetic events. Those dynamic events can be co-exist on -same file because those syntax doesn't overlap. - -This introduces a framework part which provides a unified tracefs -interface and operations. - -Link: http://lkml.kernel.org/r/154140852824.17322.12250362185969352095.stgit@devbox - -Reviewed-by: Tom Zanussi -Tested-by: Tom Zanussi -Signed-off-by: Masami Hiramatsu -Signed-off-by: Steven Rostedt (VMware) -Stable-dep-of: 4313e5a61304 ("tracing: Free buffers when a used dynamic event is removed") -Signed-off-by: Sasha Levin ---- - kernel/trace/Kconfig | 3 + - kernel/trace/Makefile | 1 + - kernel/trace/trace.c | 4 + - kernel/trace/trace_dynevent.c | 210 ++++++++++++++++++++++++++++++++++ - kernel/trace/trace_dynevent.h | 119 +++++++++++++++++++ - 5 files changed, 337 insertions(+) - create mode 100644 kernel/trace/trace_dynevent.c - create mode 100644 kernel/trace/trace_dynevent.h - -diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig -index e656d1e232da..7d7edc56eb5e 100644 ---- a/kernel/trace/Kconfig -+++ b/kernel/trace/Kconfig -@@ -518,6 +518,9 @@ config BPF_EVENTS - help - This allows the user to attach BPF programs to kprobe events. - -+config DYNAMIC_EVENTS -+ def_bool n -+ - config PROBE_EVENTS - def_bool n - -diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile -index f81dadbc7c4a..9ff3c4fa91b6 100644 ---- a/kernel/trace/Makefile -+++ b/kernel/trace/Makefile -@@ -78,6 +78,7 @@ endif - ifeq ($(CONFIG_TRACING),y) - obj-$(CONFIG_KGDB_KDB) += trace_kdb.o - endif -+obj-$(CONFIG_DYNAMIC_EVENTS) += trace_dynevent.o - obj-$(CONFIG_PROBE_EVENTS) += trace_probe.o - obj-$(CONFIG_UPROBE_EVENTS) += trace_uprobe.o - -diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c -index 5b7a6e9b0ab6..44a0bc16a859 100644 ---- a/kernel/trace/trace.c -+++ b/kernel/trace/trace.c -@@ -4655,6 +4655,10 @@ static const char readme_msg[] = - "\t\t\t traces\n" - #endif - #endif /* CONFIG_STACK_TRACER */ -+#ifdef CONFIG_DYNAMIC_EVENTS -+ " dynamic_events\t\t- Add/remove/show the generic dynamic events\n" -+ "\t\t\t Write into this file to define/undefine new trace events.\n" -+#endif - #ifdef CONFIG_KPROBE_EVENTS - " kprobe_events\t\t- Add/remove/show the kernel dynamic events\n" - "\t\t\t Write into this file to define/undefine new trace events.\n" -diff --git a/kernel/trace/trace_dynevent.c b/kernel/trace/trace_dynevent.c -new file mode 100644 -index 000000000000..f17a887abb66 ---- /dev/null -+++ b/kernel/trace/trace_dynevent.c -@@ -0,0 +1,210 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Generic dynamic event control interface -+ * -+ * Copyright (C) 2018 Masami Hiramatsu -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "trace.h" -+#include "trace_dynevent.h" -+ -+static DEFINE_MUTEX(dyn_event_ops_mutex); -+static LIST_HEAD(dyn_event_ops_list); -+ -+int dyn_event_register(struct dyn_event_operations *ops) -+{ -+ if (!ops || !ops->create || !ops->show || !ops->is_busy || -+ !ops->free || !ops->match) -+ return -EINVAL; -+ -+ INIT_LIST_HEAD(&ops->list); -+ mutex_lock(&dyn_event_ops_mutex); -+ list_add_tail(&ops->list, &dyn_event_ops_list); -+ mutex_unlock(&dyn_event_ops_mutex); -+ return 0; -+} -+ -+int dyn_event_release(int argc, char **argv, struct dyn_event_operations *type) -+{ -+ struct dyn_event *pos, *n; -+ char *system = NULL, *event, *p; -+ int ret = -ENOENT; -+ -+ if (argv[0][1] != ':') -+ return -EINVAL; -+ -+ event = &argv[0][2]; -+ p = strchr(event, '/'); -+ if (p) { -+ system = event; -+ event = p + 1; -+ *p = '\0'; -+ } -+ if (event[0] == '\0') -+ return -EINVAL; -+ -+ mutex_lock(&event_mutex); -+ for_each_dyn_event_safe(pos, n) { -+ if (type && type != pos->ops) -+ continue; -+ if (pos->ops->match(system, event, pos)) { -+ ret = pos->ops->free(pos); -+ break; -+ } -+ } -+ mutex_unlock(&event_mutex); -+ -+ return ret; -+} -+ -+static int create_dyn_event(int argc, char **argv) -+{ -+ struct dyn_event_operations *ops; -+ int ret; -+ -+ if (argv[0][0] == '-') -+ return dyn_event_release(argc, argv, NULL); -+ -+ mutex_lock(&dyn_event_ops_mutex); -+ list_for_each_entry(ops, &dyn_event_ops_list, list) { -+ ret = ops->create(argc, (const char **)argv); -+ if (!ret || ret != -ECANCELED) -+ break; -+ } -+ mutex_unlock(&dyn_event_ops_mutex); -+ if (ret == -ECANCELED) -+ ret = -EINVAL; -+ -+ return ret; -+} -+ -+/* Protected by event_mutex */ -+LIST_HEAD(dyn_event_list); -+ -+void *dyn_event_seq_start(struct seq_file *m, loff_t *pos) -+{ -+ mutex_lock(&event_mutex); -+ return seq_list_start(&dyn_event_list, *pos); -+} -+ -+void *dyn_event_seq_next(struct seq_file *m, void *v, loff_t *pos) -+{ -+ return seq_list_next(v, &dyn_event_list, pos); -+} -+ -+void dyn_event_seq_stop(struct seq_file *m, void *v) -+{ -+ mutex_unlock(&event_mutex); -+} -+ -+static int dyn_event_seq_show(struct seq_file *m, void *v) -+{ -+ struct dyn_event *ev = v; -+ -+ if (ev && ev->ops) -+ return ev->ops->show(m, ev); -+ -+ return 0; -+} -+ -+static const struct seq_operations dyn_event_seq_op = { -+ .start = dyn_event_seq_start, -+ .next = dyn_event_seq_next, -+ .stop = dyn_event_seq_stop, -+ .show = dyn_event_seq_show -+}; -+ -+/* -+ * dyn_events_release_all - Release all specific events -+ * @type: the dyn_event_operations * which filters releasing events -+ * -+ * This releases all events which ->ops matches @type. If @type is NULL, -+ * all events are released. -+ * Return -EBUSY if any of them are in use, and return other errors when -+ * it failed to free the given event. Except for -EBUSY, event releasing -+ * process will be aborted at that point and there may be some other -+ * releasable events on the list. -+ */ -+int dyn_events_release_all(struct dyn_event_operations *type) -+{ -+ struct dyn_event *ev, *tmp; -+ int ret = 0; -+ -+ mutex_lock(&event_mutex); -+ for_each_dyn_event(ev) { -+ if (type && ev->ops != type) -+ continue; -+ if (ev->ops->is_busy(ev)) { -+ ret = -EBUSY; -+ goto out; -+ } -+ } -+ for_each_dyn_event_safe(ev, tmp) { -+ if (type && ev->ops != type) -+ continue; -+ ret = ev->ops->free(ev); -+ if (ret) -+ break; -+ } -+out: -+ mutex_unlock(&event_mutex); -+ -+ return ret; -+} -+ -+static int dyn_event_open(struct inode *inode, struct file *file) -+{ -+ int ret; -+ -+ if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) { -+ ret = dyn_events_release_all(NULL); -+ if (ret < 0) -+ return ret; -+ } -+ -+ return seq_open(file, &dyn_event_seq_op); -+} -+ -+static ssize_t dyn_event_write(struct file *file, const char __user *buffer, -+ size_t count, loff_t *ppos) -+{ -+ return trace_parse_run_command(file, buffer, count, ppos, -+ create_dyn_event); -+} -+ -+static const struct file_operations dynamic_events_ops = { -+ .owner = THIS_MODULE, -+ .open = dyn_event_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = seq_release, -+ .write = dyn_event_write, -+}; -+ -+/* Make a tracefs interface for controlling dynamic events */ -+static __init int init_dynamic_event(void) -+{ -+ struct dentry *d_tracer; -+ struct dentry *entry; -+ -+ d_tracer = tracing_init_dentry(); -+ if (IS_ERR(d_tracer)) -+ return 0; -+ -+ entry = tracefs_create_file("dynamic_events", 0644, d_tracer, -+ NULL, &dynamic_events_ops); -+ -+ /* Event list interface */ -+ if (!entry) -+ pr_warn("Could not create tracefs 'dynamic_events' entry\n"); -+ -+ return 0; -+} -+fs_initcall(init_dynamic_event); -diff --git a/kernel/trace/trace_dynevent.h b/kernel/trace/trace_dynevent.h -new file mode 100644 -index 000000000000..8c334064e4d6 ---- /dev/null -+++ b/kernel/trace/trace_dynevent.h -@@ -0,0 +1,119 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Common header file for generic dynamic events. -+ */ -+ -+#ifndef _TRACE_DYNEVENT_H -+#define _TRACE_DYNEVENT_H -+ -+#include -+#include -+#include -+#include -+ -+#include "trace.h" -+ -+struct dyn_event; -+ -+/** -+ * struct dyn_event_operations - Methods for each type of dynamic events -+ * -+ * These methods must be set for each type, since there is no default method. -+ * Before using this for dyn_event_init(), it must be registered by -+ * dyn_event_register(). -+ * -+ * @create: Parse and create event method. This is invoked when user passes -+ * a event definition to dynamic_events interface. This must not destruct -+ * the arguments and return -ECANCELED if given arguments doesn't match its -+ * command prefix. -+ * @show: Showing method. This is invoked when user reads the event definitions -+ * via dynamic_events interface. -+ * @is_busy: Check whether given event is busy so that it can not be deleted. -+ * Return true if it is busy, otherwides false. -+ * @free: Delete the given event. Return 0 if success, otherwides error. -+ * @match: Check whether given event and system name match this event. -+ * Return true if it matches, otherwides false. -+ * -+ * Except for @create, these methods are called under holding event_mutex. -+ */ -+struct dyn_event_operations { -+ struct list_head list; -+ int (*create)(int argc, const char *argv[]); -+ int (*show)(struct seq_file *m, struct dyn_event *ev); -+ bool (*is_busy)(struct dyn_event *ev); -+ int (*free)(struct dyn_event *ev); -+ bool (*match)(const char *system, const char *event, -+ struct dyn_event *ev); -+}; -+ -+/* Register new dyn_event type -- must be called at first */ -+int dyn_event_register(struct dyn_event_operations *ops); -+ -+/** -+ * struct dyn_event - Dynamic event list header -+ * -+ * The dyn_event structure encapsulates a list and a pointer to the operators -+ * for making a global list of dynamic events. -+ * User must includes this in each event structure, so that those events can -+ * be added/removed via dynamic_events interface. -+ */ -+struct dyn_event { -+ struct list_head list; -+ struct dyn_event_operations *ops; -+}; -+ -+extern struct list_head dyn_event_list; -+ -+static inline -+int dyn_event_init(struct dyn_event *ev, struct dyn_event_operations *ops) -+{ -+ if (!ev || !ops) -+ return -EINVAL; -+ -+ INIT_LIST_HEAD(&ev->list); -+ ev->ops = ops; -+ return 0; -+} -+ -+static inline int dyn_event_add(struct dyn_event *ev) -+{ -+ lockdep_assert_held(&event_mutex); -+ -+ if (!ev || !ev->ops) -+ return -EINVAL; -+ -+ list_add_tail(&ev->list, &dyn_event_list); -+ return 0; -+} -+ -+static inline void dyn_event_remove(struct dyn_event *ev) -+{ -+ lockdep_assert_held(&event_mutex); -+ list_del_init(&ev->list); -+} -+ -+void *dyn_event_seq_start(struct seq_file *m, loff_t *pos); -+void *dyn_event_seq_next(struct seq_file *m, void *v, loff_t *pos); -+void dyn_event_seq_stop(struct seq_file *m, void *v); -+int dyn_events_release_all(struct dyn_event_operations *type); -+int dyn_event_release(int argc, char **argv, struct dyn_event_operations *type); -+ -+/* -+ * for_each_dyn_event - iterate over the dyn_event list -+ * @pos: the struct dyn_event * to use as a loop cursor -+ * -+ * This is just a basement of for_each macro. Wrap this for -+ * each actual event structure with ops filtering. -+ */ -+#define for_each_dyn_event(pos) \ -+ list_for_each_entry(pos, &dyn_event_list, list) -+ -+/* -+ * for_each_dyn_event - iterate over the dyn_event list safely -+ * @pos: the struct dyn_event * to use as a loop cursor -+ * @n: the struct dyn_event * to use as temporary storage -+ */ -+#define for_each_dyn_event_safe(pos, n) \ -+ list_for_each_entry_safe(pos, n, &dyn_event_list, list) -+ -+#endif --- -2.35.1 - diff --git a/queue-4.19/tracing-free-buffers-when-a-used-dynamic-event-is-re.patch b/queue-4.19/tracing-free-buffers-when-a-used-dynamic-event-is-re.patch deleted file mode 100644 index 9631f614a26..00000000000 --- a/queue-4.19/tracing-free-buffers-when-a-used-dynamic-event-is-re.patch +++ /dev/null @@ -1,211 +0,0 @@ -From 85ebec2d5dd5264e83a4dc009833f390ce61be4e Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Wed, 23 Nov 2022 17:14:34 -0500 -Subject: tracing: Free buffers when a used dynamic event is removed -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -From: Steven Rostedt (Google) - -[ Upstream commit 4313e5a613049dfc1819a6dfb5f94cf2caff9452 ] - -After 65536 dynamic events have been added and removed, the "type" field -of the event then uses the first type number that is available (not -currently used by other events). A type number is the identifier of the -binary blobs in the tracing ring buffer (known as events) to map them to -logic that can parse the binary blob. - -The issue is that if a dynamic event (like a kprobe event) is traced and -is in the ring buffer, and then that event is removed (because it is -dynamic, which means it can be created and destroyed), if another dynamic -event is created that has the same number that new event's logic on -parsing the binary blob will be used. - -To show how this can be an issue, the following can crash the kernel: - - # cd /sys/kernel/tracing - # for i in `seq 65536`; do - echo 'p:kprobes/foo do_sys_openat2 $arg1:u32' > kprobe_events - # done - -For every iteration of the above, the writing to the kprobe_events will -remove the old event and create a new one (with the same format) and -increase the type number to the next available on until the type number -reaches over 65535 which is the max number for the 16 bit type. After it -reaches that number, the logic to allocate a new number simply looks for -the next available number. When an dynamic event is removed, that number -is then available to be reused by the next dynamic event created. That is, -once the above reaches the max number, the number assigned to the event in -that loop will remain the same. - -Now that means deleting one dynamic event and created another will reuse -the previous events type number. This is where bad things can happen. -After the above loop finishes, the kprobes/foo event which reads the -do_sys_openat2 function call's first parameter as an integer. - - # echo 1 > kprobes/foo/enable - # cat /etc/passwd > /dev/null - # cat trace - cat-2211 [005] .... 2007.849603: foo: (do_sys_openat2+0x0/0x130) arg1=4294967196 - cat-2211 [005] .... 2007.849620: foo: (do_sys_openat2+0x0/0x130) arg1=4294967196 - cat-2211 [005] .... 2007.849838: foo: (do_sys_openat2+0x0/0x130) arg1=4294967196 - cat-2211 [005] .... 2007.849880: foo: (do_sys_openat2+0x0/0x130) arg1=4294967196 - # echo 0 > kprobes/foo/enable - -Now if we delete the kprobe and create a new one that reads a string: - - # echo 'p:kprobes/foo do_sys_openat2 +0($arg2):string' > kprobe_events - -And now we can the trace: - - # cat trace - sendmail-1942 [002] ..... 530.136320: foo: (do_sys_openat2+0x0/0x240) arg1= cat-2046 [004] ..... 530.930817: foo: (do_sys_openat2+0x0/0x240) arg1="������������������������������������������������������������������������������������������������" - cat-2046 [004] ..... 530.930961: foo: (do_sys_openat2+0x0/0x240) arg1="������������������������������������������������������������������������������������������������" - cat-2046 [004] ..... 530.934278: foo: (do_sys_openat2+0x0/0x240) arg1="������������������������������������������������������������������������������������������������" - cat-2046 [004] ..... 530.934563: foo: (do_sys_openat2+0x0/0x240) arg1="������������������������������������������������������������������������������������������������" - bash-1515 [007] ..... 534.299093: foo: (do_sys_openat2+0x0/0x240) arg1="kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk���������@��4Z����;Y�����U - -And dmesg has: - -================================================================== -BUG: KASAN: use-after-free in string+0xd4/0x1c0 -Read of size 1 at addr ffff88805fdbbfa0 by task cat/2049 - - CPU: 0 PID: 2049 Comm: cat Not tainted 6.1.0-rc6-test+ #641 - Hardware name: Hewlett-Packard HP Compaq Pro 6300 SFF/339A, BIOS K01 v03.03 07/14/2016 - Call Trace: - - dump_stack_lvl+0x5b/0x77 - print_report+0x17f/0x47b - kasan_report+0xad/0x130 - string+0xd4/0x1c0 - vsnprintf+0x500/0x840 - seq_buf_vprintf+0x62/0xc0 - trace_seq_printf+0x10e/0x1e0 - print_type_string+0x90/0xa0 - print_kprobe_event+0x16b/0x290 - print_trace_line+0x451/0x8e0 - s_show+0x72/0x1f0 - seq_read_iter+0x58e/0x750 - seq_read+0x115/0x160 - vfs_read+0x11d/0x460 - ksys_read+0xa9/0x130 - do_syscall_64+0x3a/0x90 - entry_SYSCALL_64_after_hwframe+0x63/0xcd - RIP: 0033:0x7fc2e972ade2 - Code: c0 e9 b2 fe ff ff 50 48 8d 3d b2 3f 0a 00 e8 05 f0 01 00 0f 1f 44 00 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 0f 05 <48> 3d 00 f0 ff ff 77 56 c3 0f 1f 44 00 00 48 83 ec 28 48 89 54 24 - RSP: 002b:00007ffc64e687c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000000 - RAX: ffffffffffffffda RBX: 0000000000020000 RCX: 00007fc2e972ade2 - RDX: 0000000000020000 RSI: 00007fc2e980d000 RDI: 0000000000000003 - RBP: 00007fc2e980d000 R08: 00007fc2e980c010 R09: 0000000000000000 - R10: 0000000000000022 R11: 0000000000000246 R12: 0000000000020f00 - R13: 0000000000000003 R14: 0000000000020000 R15: 0000000000020000 - - - The buggy address belongs to the physical page: - page:ffffea00017f6ec0 refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x5fdbb - flags: 0xfffffc0000000(node=0|zone=1|lastcpupid=0x1fffff) - raw: 000fffffc0000000 0000000000000000 ffffea00017f6ec8 0000000000000000 - raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000 - page dumped because: kasan: bad access detected - - Memory state around the buggy address: - ffff88805fdbbe80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff - ffff88805fdbbf00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff - >ffff88805fdbbf80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff - ^ - ffff88805fdbc000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff - ffff88805fdbc080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff - ================================================================== - -This was found when Zheng Yejian sent a patch to convert the event type -number assignment to use IDA, which gives the next available number, and -this bug showed up in the fuzz testing by Yujie Liu and the kernel test -robot. But after further analysis, I found that this behavior is the same -as when the event type numbers go past the 16bit max (and the above shows -that). - -As modules have a similar issue, but is dealt with by setting a -"WAS_ENABLED" flag when a module event is enabled, and when the module is -freed, if any of its events were enabled, the ring buffer that holds that -event is also cleared, to prevent reading stale events. The same can be -done for dynamic events. - -If any dynamic event that is being removed was enabled, then make sure the -buffers they were enabled in are now cleared. - -Link: https://lkml.kernel.org/r/20221123171434.545706e3@gandalf.local.home -Link: https://lore.kernel.org/all/20221110020319.1259291-1-zhengyejian1@huawei.com/ - -Cc: stable@vger.kernel.org -Cc: Andrew Morton -Depends-on: e18eb8783ec49 ("tracing: Add tracing_reset_all_online_cpus_unlocked() function") -Depends-on: 5448d44c38557 ("tracing: Add unified dynamic event framework") -Depends-on: 6212dd29683ee ("tracing/kprobes: Use dyn_event framework for kprobe events") -Depends-on: 065e63f951432 ("tracing: Only have rmmod clear buffers that its events were active in") -Depends-on: 575380da8b469 ("tracing: Only clear trace buffer on module unload if event was traced") -Fixes: 77b44d1b7c283 ("tracing/kprobes: Rename Kprobe-tracer to kprobe-event") -Reported-by: Zheng Yejian -Reported-by: Yujie Liu -Reported-by: kernel test robot -Acked-by: Masami Hiramatsu (Google) -Signed-off-by: Steven Rostedt (Google) -Signed-off-by: Sasha Levin ---- - kernel/trace/trace_dynevent.c | 2 ++ - kernel/trace/trace_events.c | 11 ++++++++++- - 2 files changed, 12 insertions(+), 1 deletion(-) - -diff --git a/kernel/trace/trace_dynevent.c b/kernel/trace/trace_dynevent.c -index f17a887abb66..303067d38619 100644 ---- a/kernel/trace/trace_dynevent.c -+++ b/kernel/trace/trace_dynevent.c -@@ -59,6 +59,7 @@ int dyn_event_release(int argc, char **argv, struct dyn_event_operations *type) - break; - } - } -+ tracing_reset_all_online_cpus(); - mutex_unlock(&event_mutex); - - return ret; -@@ -154,6 +155,7 @@ int dyn_events_release_all(struct dyn_event_operations *type) - break; - } - out: -+ tracing_reset_all_online_cpus(); - mutex_unlock(&event_mutex); - - return ret; -diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c -index d2f9146d1ad7..c9aa7b4a4235 100644 ---- a/kernel/trace/trace_events.c -+++ b/kernel/trace/trace_events.c -@@ -2369,7 +2369,10 @@ static int probe_remove_event_call(struct trace_event_call *call) - * TRACE_REG_UNREGISTER. - */ - if (file->flags & EVENT_FILE_FL_ENABLED) -- return -EBUSY; -+ goto busy; -+ -+ if (file->flags & EVENT_FILE_FL_WAS_ENABLED) -+ tr->clear_trace = true; - /* - * The do_for_each_event_file_safe() is - * a double loop. After finding the call for this -@@ -2382,6 +2385,12 @@ static int probe_remove_event_call(struct trace_event_call *call) - __trace_remove_event_call(call); - - return 0; -+ busy: -+ /* No need to clear the trace now */ -+ list_for_each_entry(tr, &ftrace_trace_arrays, list) { -+ tr->clear_trace = false; -+ } -+ return -EBUSY; - } - - /* no event_mutex version */ --- -2.35.1 -