Loading kernel/trace/trace_kprobe.c +49 −9 Original line number Diff line number Diff line Loading @@ -836,11 +836,17 @@ static void __unregister_trace_probe(struct trace_probe *tp) } /* Unregister a trace_probe and probe_event: call with locking probe_lock */ static void unregister_trace_probe(struct trace_probe *tp) static int unregister_trace_probe(struct trace_probe *tp) { /* Enabled event can not be unregistered */ if (trace_probe_is_enabled(tp)) return -EBUSY; __unregister_trace_probe(tp); list_del(&tp->list); unregister_probe_event(tp); return 0; } /* Register a trace_probe and probe_event */ Loading @@ -854,7 +860,9 @@ static int register_trace_probe(struct trace_probe *tp) /* Delete old (same name) event if exist */ old_tp = find_trace_probe(tp->call.name, tp->call.class->system); if (old_tp) { unregister_trace_probe(old_tp); ret = unregister_trace_probe(old_tp); if (ret < 0) goto end; free_trace_probe(old_tp); } Loading Loading @@ -892,6 +900,7 @@ static int trace_probe_module_callback(struct notifier_block *nb, mutex_lock(&probe_lock); list_for_each_entry(tp, &probe_list, list) { if (trace_probe_within_module(tp, mod)) { /* Don't need to check busy - this should have gone. */ __unregister_trace_probe(tp); ret = __register_trace_probe(tp); if (ret) Loading Loading @@ -1205,10 +1214,11 @@ static int create_trace_probe(int argc, char **argv) return -ENOENT; } /* delete an event */ unregister_trace_probe(tp); ret = unregister_trace_probe(tp); if (ret == 0) free_trace_probe(tp); mutex_unlock(&probe_lock); return 0; return ret; } if (argc < 2) { Loading Loading @@ -1317,18 +1327,29 @@ static int create_trace_probe(int argc, char **argv) return ret; } static void release_all_trace_probes(void) static int release_all_trace_probes(void) { struct trace_probe *tp; int ret = 0; mutex_lock(&probe_lock); /* Ensure no probe is in use. */ list_for_each_entry(tp, &probe_list, list) if (trace_probe_is_enabled(tp)) { ret = -EBUSY; goto end; } /* TODO: Use batch unregistration */ while (!list_empty(&probe_list)) { tp = list_entry(probe_list.next, struct trace_probe, list); unregister_trace_probe(tp); free_trace_probe(tp); } end: mutex_unlock(&probe_lock); return ret; } /* Probes listing interfaces */ Loading Loading @@ -1380,9 +1401,13 @@ static const struct seq_operations probes_seq_op = { static int probes_open(struct inode *inode, struct file *file) { if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) release_all_trace_probes(); int ret; if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) { ret = release_all_trace_probes(); if (ret < 0) return ret; } return seq_open(file, &probes_seq_op); } Loading Loading @@ -2055,6 +2080,21 @@ static __init int kprobe_trace_self_tests_init(void) ret = target(1, 2, 3, 4, 5, 6); /* Disable trace points before removing it */ tp = find_trace_probe("testprobe", KPROBE_EVENT_SYSTEM); if (WARN_ON_ONCE(tp == NULL)) { pr_warning("error on getting test probe.\n"); warn++; } else disable_trace_probe(tp, TP_FLAG_TRACE); tp = find_trace_probe("testprobe2", KPROBE_EVENT_SYSTEM); if (WARN_ON_ONCE(tp == NULL)) { pr_warning("error on getting 2nd test probe.\n"); warn++; } else disable_trace_probe(tp, TP_FLAG_TRACE); ret = command_trace_probe("-:testprobe"); if (WARN_ON_ONCE(ret)) { pr_warning("error on deleting a probe.\n"); Loading tools/perf/util/probe-event.c +3 −1 Original line number Diff line number Diff line Loading @@ -1956,8 +1956,10 @@ static int __del_trace_probe_event(int fd, struct str_node *ent) pr_debug("Writing event: %s\n", buf); ret = write(fd, buf, strlen(buf)); if (ret < 0) if (ret < 0) { ret = -errno; goto error; } printf("Remove event: %s\n", ent->s); return 0; Loading Loading
kernel/trace/trace_kprobe.c +49 −9 Original line number Diff line number Diff line Loading @@ -836,11 +836,17 @@ static void __unregister_trace_probe(struct trace_probe *tp) } /* Unregister a trace_probe and probe_event: call with locking probe_lock */ static void unregister_trace_probe(struct trace_probe *tp) static int unregister_trace_probe(struct trace_probe *tp) { /* Enabled event can not be unregistered */ if (trace_probe_is_enabled(tp)) return -EBUSY; __unregister_trace_probe(tp); list_del(&tp->list); unregister_probe_event(tp); return 0; } /* Register a trace_probe and probe_event */ Loading @@ -854,7 +860,9 @@ static int register_trace_probe(struct trace_probe *tp) /* Delete old (same name) event if exist */ old_tp = find_trace_probe(tp->call.name, tp->call.class->system); if (old_tp) { unregister_trace_probe(old_tp); ret = unregister_trace_probe(old_tp); if (ret < 0) goto end; free_trace_probe(old_tp); } Loading Loading @@ -892,6 +900,7 @@ static int trace_probe_module_callback(struct notifier_block *nb, mutex_lock(&probe_lock); list_for_each_entry(tp, &probe_list, list) { if (trace_probe_within_module(tp, mod)) { /* Don't need to check busy - this should have gone. */ __unregister_trace_probe(tp); ret = __register_trace_probe(tp); if (ret) Loading Loading @@ -1205,10 +1214,11 @@ static int create_trace_probe(int argc, char **argv) return -ENOENT; } /* delete an event */ unregister_trace_probe(tp); ret = unregister_trace_probe(tp); if (ret == 0) free_trace_probe(tp); mutex_unlock(&probe_lock); return 0; return ret; } if (argc < 2) { Loading Loading @@ -1317,18 +1327,29 @@ static int create_trace_probe(int argc, char **argv) return ret; } static void release_all_trace_probes(void) static int release_all_trace_probes(void) { struct trace_probe *tp; int ret = 0; mutex_lock(&probe_lock); /* Ensure no probe is in use. */ list_for_each_entry(tp, &probe_list, list) if (trace_probe_is_enabled(tp)) { ret = -EBUSY; goto end; } /* TODO: Use batch unregistration */ while (!list_empty(&probe_list)) { tp = list_entry(probe_list.next, struct trace_probe, list); unregister_trace_probe(tp); free_trace_probe(tp); } end: mutex_unlock(&probe_lock); return ret; } /* Probes listing interfaces */ Loading Loading @@ -1380,9 +1401,13 @@ static const struct seq_operations probes_seq_op = { static int probes_open(struct inode *inode, struct file *file) { if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) release_all_trace_probes(); int ret; if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) { ret = release_all_trace_probes(); if (ret < 0) return ret; } return seq_open(file, &probes_seq_op); } Loading Loading @@ -2055,6 +2080,21 @@ static __init int kprobe_trace_self_tests_init(void) ret = target(1, 2, 3, 4, 5, 6); /* Disable trace points before removing it */ tp = find_trace_probe("testprobe", KPROBE_EVENT_SYSTEM); if (WARN_ON_ONCE(tp == NULL)) { pr_warning("error on getting test probe.\n"); warn++; } else disable_trace_probe(tp, TP_FLAG_TRACE); tp = find_trace_probe("testprobe2", KPROBE_EVENT_SYSTEM); if (WARN_ON_ONCE(tp == NULL)) { pr_warning("error on getting 2nd test probe.\n"); warn++; } else disable_trace_probe(tp, TP_FLAG_TRACE); ret = command_trace_probe("-:testprobe"); if (WARN_ON_ONCE(ret)) { pr_warning("error on deleting a probe.\n"); Loading
tools/perf/util/probe-event.c +3 −1 Original line number Diff line number Diff line Loading @@ -1956,8 +1956,10 @@ static int __del_trace_probe_event(int fd, struct str_node *ent) pr_debug("Writing event: %s\n", buf); ret = write(fd, buf, strlen(buf)); if (ret < 0) if (ret < 0) { ret = -errno; goto error; } printf("Remove event: %s\n", ent->s); return 0; Loading