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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'trace-3.15-v2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace

Pull more tracing updates from Steven Rostedt:
"This includes the final patch to clean up and fix the issue with the
design of tracepoints and how a user could register a tracepoint and
have that tracepoint not be activated but no error was shown.

The design was for an out of tree module but broke in tree users. The
clean up was to remove the saving of the hash table of tracepoint
names such that they can be enabled before they exist (enabling a
module tracepoint before that module is loaded). This added more
complexity than needed. The clean up was to remove that code and just
enable tracepoints that exist or fail if they do not.

This removed a lot of code as well as the complexity that it brought.
As a side effect, instead of registering a tracepoint by its name, the
tracepoint needs to be registered with the tracepoint descriptor.
This removes having to duplicate the tracepoint names that are
enabled.

The second patch was added that simplified the way modules were
searched for.

This cleanup required changes that were in the 3.15 queue as well as
some changes that were added late in the 3.14-rc cycle. This final
change waited till the two were merged in upstream and then the change
was added and full tests were run. Unfortunately, the test found some
errors, but after it was already submitted to the for-next branch and
not to be rebased. Sparse errors were detected by Fengguang Wu's bot
tests, and my internal tests discovered that the anonymous union
initialization triggered a bug in older gcc compilers. Luckily, there
was a bugzilla for the gcc bug which gave a work around to the
problem. The third and fourth patch handled the sparse error and the
gcc bug respectively.

A final patch was tagged along to fix a missing documentation for the
README file"

* tag 'trace-3.15-v2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace:
tracing: Add missing function triggers dump and cpudump to README
tracing: Fix anonymous unions in struct ftrace_event_call
tracepoint: Fix sparse warnings in tracepoint.c
tracepoint: Simplify tracepoint module search
tracepoint: Use struct pointer instead of name hash for reg/unreg tracepoints

+360 -365
+20 -2
include/linux/ftrace_event.h
··· 7 7 #include <linux/percpu.h> 8 8 #include <linux/hardirq.h> 9 9 #include <linux/perf_event.h> 10 + #include <linux/tracepoint.h> 10 11 11 12 struct trace_array; 12 13 struct trace_buffer; ··· 233 232 TRACE_EVENT_FL_IGNORE_ENABLE_BIT, 234 233 TRACE_EVENT_FL_WAS_ENABLED_BIT, 235 234 TRACE_EVENT_FL_USE_CALL_FILTER_BIT, 235 + TRACE_EVENT_FL_TRACEPOINT_BIT, 236 236 }; 237 237 238 238 /* ··· 246 244 * (used for module unloading, if a module event is enabled, 247 245 * it is best to clear the buffers that used it). 248 246 * USE_CALL_FILTER - For ftrace internal events, don't use file filter 247 + * TRACEPOINT - Event is a tracepoint 249 248 */ 250 249 enum { 251 250 TRACE_EVENT_FL_FILTERED = (1 << TRACE_EVENT_FL_FILTERED_BIT), ··· 255 252 TRACE_EVENT_FL_IGNORE_ENABLE = (1 << TRACE_EVENT_FL_IGNORE_ENABLE_BIT), 256 253 TRACE_EVENT_FL_WAS_ENABLED = (1 << TRACE_EVENT_FL_WAS_ENABLED_BIT), 257 254 TRACE_EVENT_FL_USE_CALL_FILTER = (1 << TRACE_EVENT_FL_USE_CALL_FILTER_BIT), 255 + TRACE_EVENT_FL_TRACEPOINT = (1 << TRACE_EVENT_FL_TRACEPOINT_BIT), 258 256 }; 259 257 260 258 struct ftrace_event_call { 261 259 struct list_head list; 262 260 struct ftrace_event_class *class; 263 - char *name; 261 + union { 262 + char *name; 263 + /* Set TRACE_EVENT_FL_TRACEPOINT flag when using "tp" */ 264 + struct tracepoint *tp; 265 + }; 264 266 struct trace_event event; 265 267 const char *print_fmt; 266 268 struct event_filter *filter; ··· 279 271 * bit 3: ftrace internal event (do not enable) 280 272 * bit 4: Event was enabled by module 281 273 * bit 5: use call filter rather than file filter 274 + * bit 6: Event is a tracepoint 282 275 */ 283 276 int flags; /* static flags of different events */ 284 277 ··· 291 282 struct perf_event *); 292 283 #endif 293 284 }; 285 + 286 + static inline const char * 287 + ftrace_event_name(struct ftrace_event_call *call) 288 + { 289 + if (call->flags & TRACE_EVENT_FL_TRACEPOINT) 290 + return call->tp ? call->tp->name : NULL; 291 + else 292 + return call->name; 293 + } 294 294 295 295 struct trace_array; 296 296 struct ftrace_subsystem_dir; ··· 371 353 #define __TRACE_EVENT_FLAGS(name, value) \ 372 354 static int __init trace_init_flags_##name(void) \ 373 355 { \ 374 - event_##name.flags = value; \ 356 + event_##name.flags |= value; \ 375 357 return 0; \ 376 358 } \ 377 359 early_initcall(trace_init_flags_##name);
+6 -2
include/linux/syscalls.h
··· 119 119 static struct syscall_metadata __syscall_meta_##sname; \ 120 120 static struct ftrace_event_call __used \ 121 121 event_enter_##sname = { \ 122 - .name = "sys_enter"#sname, \ 123 122 .class = &event_class_syscall_enter, \ 123 + { \ 124 + .name = "sys_enter"#sname, \ 125 + }, \ 124 126 .event.funcs = &enter_syscall_print_funcs, \ 125 127 .data = (void *)&__syscall_meta_##sname,\ 126 128 .flags = TRACE_EVENT_FL_CAP_ANY, \ ··· 135 133 static struct syscall_metadata __syscall_meta_##sname; \ 136 134 static struct ftrace_event_call __used \ 137 135 event_exit_##sname = { \ 138 - .name = "sys_exit"#sname, \ 139 136 .class = &event_class_syscall_exit, \ 137 + { \ 138 + .name = "sys_exit"#sname, \ 139 + }, \ 140 140 .event.funcs = &exit_syscall_print_funcs, \ 141 141 .data = (void *)&__syscall_meta_##sname,\ 142 142 .flags = TRACE_EVENT_FL_CAP_ANY, \
+31 -18
include/linux/tracepoint.h
··· 6 6 * 7 7 * See Documentation/trace/tracepoints.txt. 8 8 * 9 - * (C) Copyright 2008 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> 9 + * Copyright (C) 2008-2014 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> 10 10 * 11 11 * Heavily inspired from the Linux Kernel Markers. 12 12 * ··· 21 21 22 22 struct module; 23 23 struct tracepoint; 24 + struct notifier_block; 24 25 25 26 struct tracepoint_func { 26 27 void *func; ··· 36 35 struct tracepoint_func __rcu *funcs; 37 36 }; 38 37 39 - /* 40 - * Connect a probe to a tracepoint. 41 - * Internal API, should not be used directly. 42 - */ 43 - extern int tracepoint_probe_register(const char *name, void *probe, void *data); 44 - 45 - /* 46 - * Disconnect a probe from a tracepoint. 47 - * Internal API, should not be used directly. 48 - */ 49 38 extern int 50 - tracepoint_probe_unregister(const char *name, void *probe, void *data); 39 + tracepoint_probe_register(struct tracepoint *tp, void *probe, void *data); 40 + extern int 41 + tracepoint_probe_unregister(struct tracepoint *tp, void *probe, void *data); 42 + extern void 43 + for_each_kernel_tracepoint(void (*fct)(struct tracepoint *tp, void *priv), 44 + void *priv); 51 45 52 46 #ifdef CONFIG_MODULES 53 47 struct tp_module { 54 48 struct list_head list; 55 - unsigned int num_tracepoints; 56 - struct tracepoint * const *tracepoints_ptrs; 49 + struct module *mod; 57 50 }; 51 + 58 52 bool trace_module_has_bad_taint(struct module *mod); 53 + extern int register_tracepoint_module_notifier(struct notifier_block *nb); 54 + extern int unregister_tracepoint_module_notifier(struct notifier_block *nb); 59 55 #else 60 56 static inline bool trace_module_has_bad_taint(struct module *mod) 61 57 { 62 58 return false; 59 + } 60 + static inline 61 + int register_tracepoint_module_notifier(struct notifier_block *nb) 62 + { 63 + return 0; 64 + } 65 + static inline 66 + int unregister_tracepoint_module_notifier(struct notifier_block *nb) 67 + { 68 + return 0; 63 69 } 64 70 #endif /* CONFIG_MODULES */ 65 71 ··· 79 71 { 80 72 synchronize_sched(); 81 73 } 74 + 75 + #ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS 76 + extern void syscall_regfunc(void); 77 + extern void syscall_unregfunc(void); 78 + #endif /* CONFIG_HAVE_SYSCALL_TRACEPOINTS */ 82 79 83 80 #define PARAMS(args...) args 84 81 ··· 173 160 static inline int \ 174 161 register_trace_##name(void (*probe)(data_proto), void *data) \ 175 162 { \ 176 - return tracepoint_probe_register(#name, (void *)probe, \ 177 - data); \ 163 + return tracepoint_probe_register(&__tracepoint_##name, \ 164 + (void *)probe, data); \ 178 165 } \ 179 166 static inline int \ 180 167 unregister_trace_##name(void (*probe)(data_proto), void *data) \ 181 168 { \ 182 - return tracepoint_probe_unregister(#name, (void *)probe, \ 183 - data); \ 169 + return tracepoint_probe_unregister(&__tracepoint_##name,\ 170 + (void *)probe, data); \ 184 171 } \ 185 172 static inline void \ 186 173 check_trace_callback_type_##name(void (*cb)(data_proto)) \
-3
include/trace/events/syscalls.h
··· 13 13 14 14 #ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS 15 15 16 - extern void syscall_regfunc(void); 17 - extern void syscall_unregfunc(void); 18 - 19 16 TRACE_EVENT_FN(sys_enter, 20 17 21 18 TP_PROTO(struct pt_regs *regs, long id),
+12 -3
include/trace/ftrace.h
··· 470 470 * }; 471 471 * 472 472 * static struct ftrace_event_call event_<call> = { 473 - * .name = "<call>", 474 473 * .class = event_class_<template>, 474 + * { 475 + * .tp = &__tracepoint_<call>, 476 + * }, 475 477 * .event = &ftrace_event_type_<call>, 476 478 * .print_fmt = print_fmt_<call>, 479 + * .flags = TRACE_EVENT_FL_TRACEPOINT, 477 480 * }; 478 481 * // its only safe to use pointers when doing linker tricks to 479 482 * // create an array. ··· 608 605 #define DEFINE_EVENT(template, call, proto, args) \ 609 606 \ 610 607 static struct ftrace_event_call __used event_##call = { \ 611 - .name = #call, \ 612 608 .class = &event_class_##template, \ 609 + { \ 610 + .tp = &__tracepoint_##call, \ 611 + }, \ 613 612 .event.funcs = &ftrace_event_type_funcs_##template, \ 614 613 .print_fmt = print_fmt_##template, \ 614 + .flags = TRACE_EVENT_FL_TRACEPOINT, \ 615 615 }; \ 616 616 static struct ftrace_event_call __used \ 617 617 __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call ··· 625 619 static const char print_fmt_##call[] = print; \ 626 620 \ 627 621 static struct ftrace_event_call __used event_##call = { \ 628 - .name = #call, \ 629 622 .class = &event_class_##template, \ 623 + { \ 624 + .tp = &__tracepoint_##call, \ 625 + }, \ 630 626 .event.funcs = &ftrace_event_type_funcs_##call, \ 631 627 .print_fmt = print_fmt_##call, \ 628 + .flags = TRACE_EVENT_FL_TRACEPOINT, \ 632 629 }; \ 633 630 static struct ftrace_event_call __used \ 634 631 __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call
+2
kernel/trace/trace.c
··· 3611 3611 #ifdef CONFIG_TRACER_SNAPSHOT 3612 3612 "\t\t snapshot\n" 3613 3613 #endif 3614 + "\t\t dump\n" 3615 + "\t\t cpudump\n" 3614 3616 "\t example: echo do_fault:traceoff > set_ftrace_filter\n" 3615 3617 "\t echo do_trap:traceoff:3 > set_ftrace_filter\n" 3616 3618 "\t The first one will disable tracing every time do_fault is hit\n"
+32 -23
kernel/trace/trace_events.c
··· 223 223 { 224 224 struct ftrace_event_file *file = data; 225 225 226 + WARN_ON(!(call->flags & TRACE_EVENT_FL_TRACEPOINT)); 226 227 switch (type) { 227 228 case TRACE_REG_REGISTER: 228 - return tracepoint_probe_register(call->name, 229 + return tracepoint_probe_register(call->tp, 229 230 call->class->probe, 230 231 file); 231 232 case TRACE_REG_UNREGISTER: 232 - tracepoint_probe_unregister(call->name, 233 + tracepoint_probe_unregister(call->tp, 233 234 call->class->probe, 234 235 file); 235 236 return 0; 236 237 237 238 #ifdef CONFIG_PERF_EVENTS 238 239 case TRACE_REG_PERF_REGISTER: 239 - return tracepoint_probe_register(call->name, 240 + return tracepoint_probe_register(call->tp, 240 241 call->class->perf_probe, 241 242 call); 242 243 case TRACE_REG_PERF_UNREGISTER: 243 - tracepoint_probe_unregister(call->name, 244 + tracepoint_probe_unregister(call->tp, 244 245 call->class->perf_probe, 245 246 call); 246 247 return 0; ··· 353 352 if (ret) { 354 353 tracing_stop_cmdline_record(); 355 354 pr_info("event trace: Could not enable event " 356 - "%s\n", call->name); 355 + "%s\n", ftrace_event_name(call)); 357 356 break; 358 357 } 359 358 set_bit(FTRACE_EVENT_FL_ENABLED_BIT, &file->flags); ··· 482 481 { 483 482 struct ftrace_event_file *file; 484 483 struct ftrace_event_call *call; 484 + const char *name; 485 485 int ret = -EINVAL; 486 486 487 487 list_for_each_entry(file, &tr->events, list) { 488 488 489 489 call = file->event_call; 490 + name = ftrace_event_name(call); 490 491 491 - if (!call->name || !call->class || !call->class->reg) 492 + if (!name || !call->class || !call->class->reg) 492 493 continue; 493 494 494 495 if (call->flags & TRACE_EVENT_FL_IGNORE_ENABLE) 495 496 continue; 496 497 497 498 if (match && 498 - strcmp(match, call->name) != 0 && 499 + strcmp(match, name) != 0 && 499 500 strcmp(match, call->class->system) != 0) 500 501 continue; 501 502 502 503 if (sub && strcmp(sub, call->class->system) != 0) 503 504 continue; 504 505 505 - if (event && strcmp(event, call->name) != 0) 506 + if (event && strcmp(event, name) != 0) 506 507 continue; 507 508 508 509 ftrace_event_enable_disable(file, set); ··· 702 699 703 700 if (strcmp(call->class->system, TRACE_SYSTEM) != 0) 704 701 seq_printf(m, "%s:", call->class->system); 705 - seq_printf(m, "%s\n", call->name); 702 + seq_printf(m, "%s\n", ftrace_event_name(call)); 706 703 707 704 return 0; 708 705 } ··· 795 792 mutex_lock(&event_mutex); 796 793 list_for_each_entry(file, &tr->events, list) { 797 794 call = file->event_call; 798 - if (!call->name || !call->class || !call->class->reg) 795 + if (!ftrace_event_name(call) || !call->class || !call->class->reg) 799 796 continue; 800 797 801 798 if (system && strcmp(call->class->system, system->name) != 0) ··· 910 907 911 908 switch ((unsigned long)v) { 912 909 case FORMAT_HEADER: 913 - seq_printf(m, "name: %s\n", call->name); 910 + seq_printf(m, "name: %s\n", ftrace_event_name(call)); 914 911 seq_printf(m, "ID: %d\n", call->event.type); 915 912 seq_printf(m, "format:\n"); 916 913 return 0; ··· 1530 1527 struct trace_array *tr = file->tr; 1531 1528 struct list_head *head; 1532 1529 struct dentry *d_events; 1530 + const char *name; 1533 1531 int ret; 1534 1532 1535 1533 /* ··· 1544 1540 } else 1545 1541 d_events = parent; 1546 1542 1547 - file->dir = debugfs_create_dir(call->name, d_events); 1543 + name = ftrace_event_name(call); 1544 + file->dir = debugfs_create_dir(name, d_events); 1548 1545 if (!file->dir) { 1549 1546 pr_warning("Could not create debugfs '%s' directory\n", 1550 - call->name); 1547 + name); 1551 1548 return -1; 1552 1549 } 1553 1550 ··· 1572 1567 ret = call->class->define_fields(call); 1573 1568 if (ret < 0) { 1574 1569 pr_warning("Could not initialize trace point" 1575 - " events/%s\n", call->name); 1570 + " events/%s\n", name); 1576 1571 return -1; 1577 1572 } 1578 1573 } ··· 1636 1631 static int event_init(struct ftrace_event_call *call) 1637 1632 { 1638 1633 int ret = 0; 1634 + const char *name; 1639 1635 1640 - if (WARN_ON(!call->name)) 1636 + name = ftrace_event_name(call); 1637 + if (WARN_ON(!name)) 1641 1638 return -EINVAL; 1642 1639 1643 1640 if (call->class->raw_init) { 1644 1641 ret = call->class->raw_init(call); 1645 1642 if (ret < 0 && ret != -ENOSYS) 1646 1643 pr_warn("Could not initialize trace events/%s\n", 1647 - call->name); 1644 + name); 1648 1645 } 1649 1646 1650 1647 return ret; ··· 1892 1885 ret = __trace_add_new_event(call, tr); 1893 1886 if (ret < 0) 1894 1887 pr_warning("Could not create directory for event %s\n", 1895 - call->name); 1888 + ftrace_event_name(call)); 1896 1889 } 1897 1890 } 1898 1891 ··· 1901 1894 { 1902 1895 struct ftrace_event_file *file; 1903 1896 struct ftrace_event_call *call; 1897 + const char *name; 1904 1898 1905 1899 list_for_each_entry(file, &tr->events, list) { 1906 1900 1907 1901 call = file->event_call; 1902 + name = ftrace_event_name(call); 1908 1903 1909 - if (!call->name || !call->class || !call->class->reg) 1904 + if (!name || !call->class || !call->class->reg) 1910 1905 continue; 1911 1906 1912 1907 if (call->flags & TRACE_EVENT_FL_IGNORE_ENABLE) 1913 1908 continue; 1914 1909 1915 - if (strcmp(event, call->name) == 0 && 1910 + if (strcmp(event, name) == 0 && 1916 1911 strcmp(system, call->class->system) == 0) 1917 1912 return file; 1918 1913 } ··· 1982 1973 seq_printf(m, "%s:%s:%s", 1983 1974 data->enable ? ENABLE_EVENT_STR : DISABLE_EVENT_STR, 1984 1975 data->file->event_call->class->system, 1985 - data->file->event_call->name); 1976 + ftrace_event_name(data->file->event_call)); 1986 1977 1987 1978 if (data->count == -1) 1988 1979 seq_printf(m, ":unlimited\n"); ··· 2202 2193 ret = event_create_dir(tr->event_dir, file); 2203 2194 if (ret < 0) 2204 2195 pr_warning("Could not create directory for event %s\n", 2205 - file->event_call->name); 2196 + ftrace_event_name(file->event_call)); 2206 2197 } 2207 2198 } 2208 2199 ··· 2226 2217 ret = __trace_early_add_new_event(call, tr); 2227 2218 if (ret < 0) 2228 2219 pr_warning("Could not create early event %s\n", 2229 - call->name); 2220 + ftrace_event_name(call)); 2230 2221 } 2231 2222 } 2232 2223 ··· 2558 2549 continue; 2559 2550 #endif 2560 2551 2561 - pr_info("Testing event %s: ", call->name); 2552 + pr_info("Testing event %s: ", ftrace_event_name(call)); 2562 2553 2563 2554 /* 2564 2555 * If an event is already enabled, someone is using
+1 -1
kernel/trace/trace_events_trigger.c
··· 1095 1095 seq_printf(m, "%s:%s:%s", 1096 1096 enable_data->enable ? ENABLE_EVENT_STR : DISABLE_EVENT_STR, 1097 1097 enable_data->file->event_call->class->system, 1098 - enable_data->file->event_call->name); 1098 + ftrace_event_name(enable_data->file->event_call)); 1099 1099 1100 1100 if (data->count == -1) 1101 1101 seq_puts(m, ":unlimited");
+4 -2
kernel/trace/trace_export.c
··· 173 173 }; \ 174 174 \ 175 175 struct ftrace_event_call __used event_##call = { \ 176 - .name = #call, \ 177 - .event.type = etype, \ 178 176 .class = &event_class_ftrace_##call, \ 177 + { \ 178 + .name = #call, \ 179 + }, \ 180 + .event.type = etype, \ 179 181 .print_fmt = print, \ 180 182 .flags = TRACE_EVENT_FL_IGNORE_ENABLE | TRACE_EVENT_FL_USE_CALL_FILTER, \ 181 183 }; \
+13 -8
kernel/trace/trace_kprobe.c
··· 341 341 struct trace_kprobe *tk; 342 342 343 343 list_for_each_entry(tk, &probe_list, list) 344 - if (strcmp(tk->tp.call.name, event) == 0 && 344 + if (strcmp(ftrace_event_name(&tk->tp.call), event) == 0 && 345 345 strcmp(tk->tp.call.class->system, group) == 0) 346 346 return tk; 347 347 return NULL; ··· 516 516 mutex_lock(&probe_lock); 517 517 518 518 /* Delete old (same name) event if exist */ 519 - old_tk = find_trace_kprobe(tk->tp.call.name, tk->tp.call.class->system); 519 + old_tk = find_trace_kprobe(ftrace_event_name(&tk->tp.call), 520 + tk->tp.call.class->system); 520 521 if (old_tk) { 521 522 ret = unregister_trace_kprobe(old_tk); 522 523 if (ret < 0) ··· 565 564 if (ret) 566 565 pr_warning("Failed to re-register probe %s on" 567 566 "%s: %d\n", 568 - tk->tp.call.name, mod->name, ret); 567 + ftrace_event_name(&tk->tp.call), 568 + mod->name, ret); 569 569 } 570 570 } 571 571 mutex_unlock(&probe_lock); ··· 820 818 int i; 821 819 822 820 seq_printf(m, "%c", trace_kprobe_is_return(tk) ? 'r' : 'p'); 823 - seq_printf(m, ":%s/%s", tk->tp.call.class->system, tk->tp.call.name); 821 + seq_printf(m, ":%s/%s", tk->tp.call.class->system, 822 + ftrace_event_name(&tk->tp.call)); 824 823 825 824 if (!tk->symbol) 826 825 seq_printf(m, " 0x%p", tk->rp.kp.addr); ··· 879 876 { 880 877 struct trace_kprobe *tk = v; 881 878 882 - seq_printf(m, " %-44s %15lu %15lu\n", tk->tp.call.name, tk->nhit, 879 + seq_printf(m, " %-44s %15lu %15lu\n", 880 + ftrace_event_name(&tk->tp.call), tk->nhit, 883 881 tk->rp.kp.nmissed); 884 882 885 883 return 0; ··· 1015 1011 field = (struct kprobe_trace_entry_head *)iter->ent; 1016 1012 tp = container_of(event, struct trace_probe, call.event); 1017 1013 1018 - if (!trace_seq_printf(s, "%s: (", tp->call.name)) 1014 + if (!trace_seq_printf(s, "%s: (", ftrace_event_name(&tp->call))) 1019 1015 goto partial; 1020 1016 1021 1017 if (!seq_print_ip_sym(s, field->ip, flags | TRACE_ITER_SYM_OFFSET)) ··· 1051 1047 field = (struct kretprobe_trace_entry_head *)iter->ent; 1052 1048 tp = container_of(event, struct trace_probe, call.event); 1053 1049 1054 - if (!trace_seq_printf(s, "%s: (", tp->call.name)) 1050 + if (!trace_seq_printf(s, "%s: (", ftrace_event_name(&tp->call))) 1055 1051 goto partial; 1056 1052 1057 1053 if (!seq_print_ip_sym(s, field->ret_ip, flags | TRACE_ITER_SYM_OFFSET)) ··· 1290 1286 call->data = tk; 1291 1287 ret = trace_add_event_call(call); 1292 1288 if (ret) { 1293 - pr_info("Failed to register kprobe event: %s\n", call->name); 1289 + pr_info("Failed to register kprobe event: %s\n", 1290 + ftrace_event_name(call)); 1294 1291 kfree(call->print_fmt); 1295 1292 unregister_ftrace_event(&call->event); 1296 1293 }
+1 -1
kernel/trace/trace_output.c
··· 431 431 } 432 432 433 433 trace_seq_init(p); 434 - ret = trace_seq_printf(s, "%s: ", event->name); 434 + ret = trace_seq_printf(s, "%s: ", ftrace_event_name(event)); 435 435 if (!ret) 436 436 return TRACE_TYPE_PARTIAL_LINE; 437 437
+13 -7
kernel/trace/trace_uprobe.c
··· 294 294 struct trace_uprobe *tu; 295 295 296 296 list_for_each_entry(tu, &uprobe_list, list) 297 - if (strcmp(tu->tp.call.name, event) == 0 && 297 + if (strcmp(ftrace_event_name(&tu->tp.call), event) == 0 && 298 298 strcmp(tu->tp.call.class->system, group) == 0) 299 299 return tu; 300 300 ··· 324 324 mutex_lock(&uprobe_lock); 325 325 326 326 /* register as an event */ 327 - old_tu = find_probe_event(tu->tp.call.name, tu->tp.call.class->system); 327 + old_tu = find_probe_event(ftrace_event_name(&tu->tp.call), 328 + tu->tp.call.class->system); 328 329 if (old_tu) { 329 330 /* delete old event */ 330 331 ret = unregister_trace_uprobe(old_tu); ··· 600 599 char c = is_ret_probe(tu) ? 'r' : 'p'; 601 600 int i; 602 601 603 - seq_printf(m, "%c:%s/%s", c, tu->tp.call.class->system, tu->tp.call.name); 602 + seq_printf(m, "%c:%s/%s", c, tu->tp.call.class->system, 603 + ftrace_event_name(&tu->tp.call)); 604 604 seq_printf(m, " %s:0x%p", tu->filename, (void *)tu->offset); 605 605 606 606 for (i = 0; i < tu->tp.nr_args; i++) ··· 651 649 { 652 650 struct trace_uprobe *tu = v; 653 651 654 - seq_printf(m, " %s %-44s %15lu\n", tu->filename, tu->tp.call.name, tu->nhit); 652 + seq_printf(m, " %s %-44s %15lu\n", tu->filename, 653 + ftrace_event_name(&tu->tp.call), tu->nhit); 655 654 return 0; 656 655 } 657 656 ··· 847 844 tu = container_of(event, struct trace_uprobe, tp.call.event); 848 845 849 846 if (is_ret_probe(tu)) { 850 - if (!trace_seq_printf(s, "%s: (0x%lx <- 0x%lx)", tu->tp.call.name, 847 + if (!trace_seq_printf(s, "%s: (0x%lx <- 0x%lx)", 848 + ftrace_event_name(&tu->tp.call), 851 849 entry->vaddr[1], entry->vaddr[0])) 852 850 goto partial; 853 851 data = DATAOF_TRACE_ENTRY(entry, true); 854 852 } else { 855 - if (!trace_seq_printf(s, "%s: (0x%lx)", tu->tp.call.name, 853 + if (!trace_seq_printf(s, "%s: (0x%lx)", 854 + ftrace_event_name(&tu->tp.call), 856 855 entry->vaddr[0])) 857 856 goto partial; 858 857 data = DATAOF_TRACE_ENTRY(entry, false); ··· 1280 1275 ret = trace_add_event_call(call); 1281 1276 1282 1277 if (ret) { 1283 - pr_info("Failed to register uprobe event: %s\n", call->name); 1278 + pr_info("Failed to register uprobe event: %s\n", 1279 + ftrace_event_name(call)); 1284 1280 kfree(call->print_fmt); 1285 1281 unregister_ftrace_event(&call->event); 1286 1282 }
+225 -295
kernel/tracepoint.c
··· 1 1 /* 2 - * Copyright (C) 2008 Mathieu Desnoyers 2 + * Copyright (C) 2008-2014 Mathieu Desnoyers 3 3 * 4 4 * This program is free software; you can redistribute it and/or modify 5 5 * it under the terms of the GNU General Public License as published by ··· 33 33 /* Set to 1 to enable tracepoint debug output */ 34 34 static const int tracepoint_debug; 35 35 36 - /* 37 - * Tracepoints mutex protects the builtin and module tracepoints and the hash 38 - * table, as well as the local module list. 39 - */ 40 - static DEFINE_MUTEX(tracepoints_mutex); 41 - 42 36 #ifdef CONFIG_MODULES 43 - /* Local list of struct module */ 37 + /* 38 + * Tracepoint module list mutex protects the local module list. 39 + */ 40 + static DEFINE_MUTEX(tracepoint_module_list_mutex); 41 + 42 + /* Local list of struct tp_module */ 44 43 static LIST_HEAD(tracepoint_module_list); 45 44 #endif /* CONFIG_MODULES */ 46 45 47 46 /* 48 - * Tracepoint hash table, containing the active tracepoints. 49 - * Protected by tracepoints_mutex. 47 + * tracepoints_mutex protects the builtin and module tracepoints. 48 + * tracepoints_mutex nests inside tracepoint_module_list_mutex. 50 49 */ 51 - #define TRACEPOINT_HASH_BITS 6 52 - #define TRACEPOINT_TABLE_SIZE (1 << TRACEPOINT_HASH_BITS) 53 - static struct hlist_head tracepoint_table[TRACEPOINT_TABLE_SIZE]; 50 + static DEFINE_MUTEX(tracepoints_mutex); 54 51 55 52 /* 56 53 * Note about RCU : 57 54 * It is used to delay the free of multiple probes array until a quiescent 58 55 * state is reached. 59 - * Tracepoint entries modifications are protected by the tracepoints_mutex. 60 56 */ 61 - struct tracepoint_entry { 62 - struct hlist_node hlist; 63 - struct tracepoint_func *funcs; 64 - int refcount; /* Number of times armed. 0 if disarmed. */ 65 - int enabled; /* Tracepoint enabled */ 66 - char name[0]; 67 - }; 68 - 69 57 struct tp_probes { 70 58 struct rcu_head rcu; 71 59 struct tracepoint_func probes[0]; ··· 80 92 } 81 93 } 82 94 83 - static void debug_print_probes(struct tracepoint_entry *entry) 95 + static void debug_print_probes(struct tracepoint_func *funcs) 84 96 { 85 97 int i; 86 98 87 - if (!tracepoint_debug || !entry->funcs) 99 + if (!tracepoint_debug || !funcs) 88 100 return; 89 101 90 - for (i = 0; entry->funcs[i].func; i++) 91 - printk(KERN_DEBUG "Probe %d : %p\n", i, entry->funcs[i].func); 102 + for (i = 0; funcs[i].func; i++) 103 + printk(KERN_DEBUG "Probe %d : %p\n", i, funcs[i].func); 92 104 } 93 105 94 - static struct tracepoint_func * 95 - tracepoint_entry_add_probe(struct tracepoint_entry *entry, 96 - void *probe, void *data) 106 + static struct tracepoint_func *func_add(struct tracepoint_func **funcs, 107 + struct tracepoint_func *tp_func) 97 108 { 98 109 int nr_probes = 0; 99 110 struct tracepoint_func *old, *new; 100 111 101 - if (WARN_ON(!probe)) 112 + if (WARN_ON(!tp_func->func)) 102 113 return ERR_PTR(-EINVAL); 103 114 104 - debug_print_probes(entry); 105 - old = entry->funcs; 115 + debug_print_probes(*funcs); 116 + old = *funcs; 106 117 if (old) { 107 118 /* (N -> N+1), (N != 0, 1) probes */ 108 119 for (nr_probes = 0; old[nr_probes].func; nr_probes++) 109 - if (old[nr_probes].func == probe && 110 - old[nr_probes].data == data) 120 + if (old[nr_probes].func == tp_func->func && 121 + old[nr_probes].data == tp_func->data) 111 122 return ERR_PTR(-EEXIST); 112 123 } 113 124 /* + 2 : one for new probe, one for NULL func */ ··· 115 128 return ERR_PTR(-ENOMEM); 116 129 if (old) 117 130 memcpy(new, old, nr_probes * sizeof(struct tracepoint_func)); 118 - new[nr_probes].func = probe; 119 - new[nr_probes].data = data; 131 + new[nr_probes] = *tp_func; 120 132 new[nr_probes + 1].func = NULL; 121 - entry->refcount = nr_probes + 1; 122 - entry->funcs = new; 123 - debug_print_probes(entry); 133 + *funcs = new; 134 + debug_print_probes(*funcs); 124 135 return old; 125 136 } 126 137 127 - static void * 128 - tracepoint_entry_remove_probe(struct tracepoint_entry *entry, 129 - void *probe, void *data) 138 + static void *func_remove(struct tracepoint_func **funcs, 139 + struct tracepoint_func *tp_func) 130 140 { 131 141 int nr_probes = 0, nr_del = 0, i; 132 142 struct tracepoint_func *old, *new; 133 143 134 - old = entry->funcs; 144 + old = *funcs; 135 145 136 146 if (!old) 137 147 return ERR_PTR(-ENOENT); 138 148 139 - debug_print_probes(entry); 149 + debug_print_probes(*funcs); 140 150 /* (N -> M), (N > 1, M >= 0) probes */ 141 - if (probe) { 151 + if (tp_func->func) { 142 152 for (nr_probes = 0; old[nr_probes].func; nr_probes++) { 143 - if (old[nr_probes].func == probe && 144 - old[nr_probes].data == data) 153 + if (old[nr_probes].func == tp_func->func && 154 + old[nr_probes].data == tp_func->data) 145 155 nr_del++; 146 156 } 147 157 } ··· 149 165 */ 150 166 if (nr_probes - nr_del == 0) { 151 167 /* N -> 0, (N > 1) */ 152 - entry->funcs = NULL; 153 - entry->refcount = 0; 154 - debug_print_probes(entry); 168 + *funcs = NULL; 169 + debug_print_probes(*funcs); 155 170 return old; 156 171 } else { 157 172 int j = 0; ··· 160 177 if (new == NULL) 161 178 return ERR_PTR(-ENOMEM); 162 179 for (i = 0; old[i].func; i++) 163 - if (old[i].func != probe || old[i].data != data) 180 + if (old[i].func != tp_func->func 181 + || old[i].data != tp_func->data) 164 182 new[j++] = old[i]; 165 183 new[nr_probes - nr_del].func = NULL; 166 - entry->refcount = nr_probes - nr_del; 167 - entry->funcs = new; 184 + *funcs = new; 168 185 } 169 - debug_print_probes(entry); 186 + debug_print_probes(*funcs); 170 187 return old; 171 188 } 172 189 173 190 /* 174 - * Get tracepoint if the tracepoint is present in the tracepoint hash table. 175 - * Must be called with tracepoints_mutex held. 176 - * Returns NULL if not present. 191 + * Add the probe function to a tracepoint. 177 192 */ 178 - static struct tracepoint_entry *get_tracepoint(const char *name) 193 + static int tracepoint_add_func(struct tracepoint *tp, 194 + struct tracepoint_func *func) 179 195 { 180 - struct hlist_head *head; 181 - struct tracepoint_entry *e; 182 - u32 hash = jhash(name, strlen(name), 0); 196 + struct tracepoint_func *old, *tp_funcs; 183 197 184 - head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE - 1)]; 185 - hlist_for_each_entry(e, head, hlist) { 186 - if (!strcmp(name, e->name)) 187 - return e; 198 + if (tp->regfunc && !static_key_enabled(&tp->key)) 199 + tp->regfunc(); 200 + 201 + tp_funcs = rcu_dereference_protected(tp->funcs, 202 + lockdep_is_held(&tracepoints_mutex)); 203 + old = func_add(&tp_funcs, func); 204 + if (IS_ERR(old)) { 205 + WARN_ON_ONCE(1); 206 + return PTR_ERR(old); 188 207 } 189 - return NULL; 190 - } 191 - 192 - /* 193 - * Add the tracepoint to the tracepoint hash table. Must be called with 194 - * tracepoints_mutex held. 195 - */ 196 - static struct tracepoint_entry *add_tracepoint(const char *name) 197 - { 198 - struct hlist_head *head; 199 - struct tracepoint_entry *e; 200 - size_t name_len = strlen(name) + 1; 201 - u32 hash = jhash(name, name_len-1, 0); 202 - 203 - head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE - 1)]; 204 - hlist_for_each_entry(e, head, hlist) { 205 - if (!strcmp(name, e->name)) { 206 - printk(KERN_NOTICE 207 - "tracepoint %s busy\n", name); 208 - return ERR_PTR(-EEXIST); /* Already there */ 209 - } 210 - } 211 - /* 212 - * Using kmalloc here to allocate a variable length element. Could 213 - * cause some memory fragmentation if overused. 214 - */ 215 - e = kmalloc(sizeof(struct tracepoint_entry) + name_len, GFP_KERNEL); 216 - if (!e) 217 - return ERR_PTR(-ENOMEM); 218 - memcpy(&e->name[0], name, name_len); 219 - e->funcs = NULL; 220 - e->refcount = 0; 221 - e->enabled = 0; 222 - hlist_add_head(&e->hlist, head); 223 - return e; 224 - } 225 - 226 - /* 227 - * Remove the tracepoint from the tracepoint hash table. Must be called with 228 - * mutex_lock held. 229 - */ 230 - static inline void remove_tracepoint(struct tracepoint_entry *e) 231 - { 232 - hlist_del(&e->hlist); 233 - kfree(e); 234 - } 235 - 236 - /* 237 - * Sets the probe callback corresponding to one tracepoint. 238 - */ 239 - static void set_tracepoint(struct tracepoint_entry **entry, 240 - struct tracepoint *elem, int active) 241 - { 242 - WARN_ON(strcmp((*entry)->name, elem->name) != 0); 243 - 244 - if (elem->regfunc && !static_key_enabled(&elem->key) && active) 245 - elem->regfunc(); 246 - else if (elem->unregfunc && static_key_enabled(&elem->key) && !active) 247 - elem->unregfunc(); 208 + release_probes(old); 248 209 249 210 /* 250 211 * rcu_assign_pointer has a smp_wmb() which makes sure that the new ··· 197 270 * include/linux/tracepoints.h. A matching smp_read_barrier_depends() 198 271 * is used. 199 272 */ 200 - rcu_assign_pointer(elem->funcs, (*entry)->funcs); 201 - if (active && !static_key_enabled(&elem->key)) 202 - static_key_slow_inc(&elem->key); 203 - else if (!active && static_key_enabled(&elem->key)) 204 - static_key_slow_dec(&elem->key); 273 + rcu_assign_pointer(tp->funcs, tp_funcs); 274 + if (!static_key_enabled(&tp->key)) 275 + static_key_slow_inc(&tp->key); 276 + return 0; 205 277 } 206 278 207 279 /* 208 - * Disable a tracepoint and its probe callback. 280 + * Remove a probe function from a tracepoint. 209 281 * Note: only waiting an RCU period after setting elem->call to the empty 210 282 * function insures that the original callback is not used anymore. This insured 211 283 * by preempt_disable around the call site. 212 284 */ 213 - static void disable_tracepoint(struct tracepoint *elem) 285 + static int tracepoint_remove_func(struct tracepoint *tp, 286 + struct tracepoint_func *func) 214 287 { 215 - if (elem->unregfunc && static_key_enabled(&elem->key)) 216 - elem->unregfunc(); 288 + struct tracepoint_func *old, *tp_funcs; 217 289 218 - if (static_key_enabled(&elem->key)) 219 - static_key_slow_dec(&elem->key); 220 - rcu_assign_pointer(elem->funcs, NULL); 221 - } 222 - 223 - /** 224 - * tracepoint_update_probe_range - Update a probe range 225 - * @begin: beginning of the range 226 - * @end: end of the range 227 - * 228 - * Updates the probe callback corresponding to a range of tracepoints. 229 - * Called with tracepoints_mutex held. 230 - */ 231 - static void tracepoint_update_probe_range(struct tracepoint * const *begin, 232 - struct tracepoint * const *end) 233 - { 234 - struct tracepoint * const *iter; 235 - struct tracepoint_entry *mark_entry; 236 - 237 - if (!begin) 238 - return; 239 - 240 - for (iter = begin; iter < end; iter++) { 241 - mark_entry = get_tracepoint((*iter)->name); 242 - if (mark_entry) { 243 - set_tracepoint(&mark_entry, *iter, 244 - !!mark_entry->refcount); 245 - mark_entry->enabled = !!mark_entry->refcount; 246 - } else { 247 - disable_tracepoint(*iter); 248 - } 290 + tp_funcs = rcu_dereference_protected(tp->funcs, 291 + lockdep_is_held(&tracepoints_mutex)); 292 + old = func_remove(&tp_funcs, func); 293 + if (IS_ERR(old)) { 294 + WARN_ON_ONCE(1); 295 + return PTR_ERR(old); 249 296 } 250 - } 297 + release_probes(old); 251 298 252 - #ifdef CONFIG_MODULES 253 - void module_update_tracepoints(void) 254 - { 255 - struct tp_module *tp_mod; 299 + if (!tp_funcs) { 300 + /* Removed last function */ 301 + if (tp->unregfunc && static_key_enabled(&tp->key)) 302 + tp->unregfunc(); 256 303 257 - list_for_each_entry(tp_mod, &tracepoint_module_list, list) 258 - tracepoint_update_probe_range(tp_mod->tracepoints_ptrs, 259 - tp_mod->tracepoints_ptrs + tp_mod->num_tracepoints); 260 - } 261 - #else /* CONFIG_MODULES */ 262 - void module_update_tracepoints(void) 263 - { 264 - } 265 - #endif /* CONFIG_MODULES */ 266 - 267 - 268 - /* 269 - * Update probes, removing the faulty probes. 270 - * Called with tracepoints_mutex held. 271 - */ 272 - static void tracepoint_update_probes(void) 273 - { 274 - /* Core kernel tracepoints */ 275 - tracepoint_update_probe_range(__start___tracepoints_ptrs, 276 - __stop___tracepoints_ptrs); 277 - /* tracepoints in modules. */ 278 - module_update_tracepoints(); 279 - } 280 - 281 - static struct tracepoint_func * 282 - tracepoint_add_probe(const char *name, void *probe, void *data) 283 - { 284 - struct tracepoint_entry *entry; 285 - struct tracepoint_func *old; 286 - 287 - entry = get_tracepoint(name); 288 - if (!entry) { 289 - entry = add_tracepoint(name); 290 - if (IS_ERR(entry)) 291 - return (struct tracepoint_func *)entry; 304 + if (static_key_enabled(&tp->key)) 305 + static_key_slow_dec(&tp->key); 292 306 } 293 - old = tracepoint_entry_add_probe(entry, probe, data); 294 - if (IS_ERR(old) && !entry->refcount) 295 - remove_tracepoint(entry); 296 - return old; 307 + rcu_assign_pointer(tp->funcs, tp_funcs); 308 + return 0; 297 309 } 298 310 299 311 /** 300 312 * tracepoint_probe_register - Connect a probe to a tracepoint 301 - * @name: tracepoint name 313 + * @tp: tracepoint 302 314 * @probe: probe handler 303 - * @data: probe private data 304 315 * 305 - * Returns: 306 - * - 0 if the probe was successfully registered, and tracepoint 307 - * callsites are currently loaded for that probe, 308 - * - -ENODEV if the probe was successfully registered, but no tracepoint 309 - * callsite is currently loaded for that probe, 310 - * - other negative error value on error. 311 - * 312 - * When tracepoint_probe_register() returns either 0 or -ENODEV, 313 - * parameters @name, @probe, and @data may be used by the tracepoint 314 - * infrastructure until the probe is unregistered. 315 - * 316 - * The probe address must at least be aligned on the architecture pointer size. 316 + * Returns 0 if ok, error value on error. 317 + * Note: if @tp is within a module, the caller is responsible for 318 + * unregistering the probe before the module is gone. This can be 319 + * performed either with a tracepoint module going notifier, or from 320 + * within module exit functions. 317 321 */ 318 - int tracepoint_probe_register(const char *name, void *probe, void *data) 322 + int tracepoint_probe_register(struct tracepoint *tp, void *probe, void *data) 319 323 { 320 - struct tracepoint_func *old; 321 - struct tracepoint_entry *entry; 322 - int ret = 0; 324 + struct tracepoint_func tp_func; 325 + int ret; 323 326 324 327 mutex_lock(&tracepoints_mutex); 325 - old = tracepoint_add_probe(name, probe, data); 326 - if (IS_ERR(old)) { 327 - mutex_unlock(&tracepoints_mutex); 328 - return PTR_ERR(old); 329 - } 330 - tracepoint_update_probes(); /* may update entry */ 331 - entry = get_tracepoint(name); 332 - /* Make sure the entry was enabled */ 333 - if (!entry || !entry->enabled) 334 - ret = -ENODEV; 328 + tp_func.func = probe; 329 + tp_func.data = data; 330 + ret = tracepoint_add_func(tp, &tp_func); 335 331 mutex_unlock(&tracepoints_mutex); 336 - release_probes(old); 337 332 return ret; 338 333 } 339 334 EXPORT_SYMBOL_GPL(tracepoint_probe_register); 340 335 341 - static struct tracepoint_func * 342 - tracepoint_remove_probe(const char *name, void *probe, void *data) 343 - { 344 - struct tracepoint_entry *entry; 345 - struct tracepoint_func *old; 346 - 347 - entry = get_tracepoint(name); 348 - if (!entry) 349 - return ERR_PTR(-ENOENT); 350 - old = tracepoint_entry_remove_probe(entry, probe, data); 351 - if (IS_ERR(old)) 352 - return old; 353 - if (!entry->refcount) 354 - remove_tracepoint(entry); 355 - return old; 356 - } 357 - 358 336 /** 359 337 * tracepoint_probe_unregister - Disconnect a probe from a tracepoint 360 - * @name: tracepoint name 338 + * @tp: tracepoint 361 339 * @probe: probe function pointer 362 - * @data: probe private data 363 340 * 364 - * We do not need to call a synchronize_sched to make sure the probes have 365 - * finished running before doing a module unload, because the module unload 366 - * itself uses stop_machine(), which insures that every preempt disabled section 367 - * have finished. 341 + * Returns 0 if ok, error value on error. 368 342 */ 369 - int tracepoint_probe_unregister(const char *name, void *probe, void *data) 343 + int tracepoint_probe_unregister(struct tracepoint *tp, void *probe, void *data) 370 344 { 371 - struct tracepoint_func *old; 345 + struct tracepoint_func tp_func; 346 + int ret; 372 347 373 348 mutex_lock(&tracepoints_mutex); 374 - old = tracepoint_remove_probe(name, probe, data); 375 - if (IS_ERR(old)) { 376 - mutex_unlock(&tracepoints_mutex); 377 - return PTR_ERR(old); 378 - } 379 - tracepoint_update_probes(); /* may update entry */ 349 + tp_func.func = probe; 350 + tp_func.data = data; 351 + ret = tracepoint_remove_func(tp, &tp_func); 380 352 mutex_unlock(&tracepoints_mutex); 381 - release_probes(old); 382 - return 0; 353 + return ret; 383 354 } 384 355 EXPORT_SYMBOL_GPL(tracepoint_probe_unregister); 385 - 386 356 387 357 #ifdef CONFIG_MODULES 388 358 bool trace_module_has_bad_taint(struct module *mod) 389 359 { 390 360 return mod->taints & ~((1 << TAINT_OOT_MODULE) | (1 << TAINT_CRAP) | 391 361 (1 << TAINT_UNSIGNED_MODULE)); 362 + } 363 + 364 + static BLOCKING_NOTIFIER_HEAD(tracepoint_notify_list); 365 + 366 + /** 367 + * register_tracepoint_notifier - register tracepoint coming/going notifier 368 + * @nb: notifier block 369 + * 370 + * Notifiers registered with this function are called on module 371 + * coming/going with the tracepoint_module_list_mutex held. 372 + * The notifier block callback should expect a "struct tp_module" data 373 + * pointer. 374 + */ 375 + int register_tracepoint_module_notifier(struct notifier_block *nb) 376 + { 377 + struct tp_module *tp_mod; 378 + int ret; 379 + 380 + mutex_lock(&tracepoint_module_list_mutex); 381 + ret = blocking_notifier_chain_register(&tracepoint_notify_list, nb); 382 + if (ret) 383 + goto end; 384 + list_for_each_entry(tp_mod, &tracepoint_module_list, list) 385 + (void) nb->notifier_call(nb, MODULE_STATE_COMING, tp_mod); 386 + end: 387 + mutex_unlock(&tracepoint_module_list_mutex); 388 + return ret; 389 + } 390 + EXPORT_SYMBOL_GPL(register_tracepoint_module_notifier); 391 + 392 + /** 393 + * unregister_tracepoint_notifier - unregister tracepoint coming/going notifier 394 + * @nb: notifier block 395 + * 396 + * The notifier block callback should expect a "struct tp_module" data 397 + * pointer. 398 + */ 399 + int unregister_tracepoint_module_notifier(struct notifier_block *nb) 400 + { 401 + struct tp_module *tp_mod; 402 + int ret; 403 + 404 + mutex_lock(&tracepoint_module_list_mutex); 405 + ret = blocking_notifier_chain_unregister(&tracepoint_notify_list, nb); 406 + if (ret) 407 + goto end; 408 + list_for_each_entry(tp_mod, &tracepoint_module_list, list) 409 + (void) nb->notifier_call(nb, MODULE_STATE_GOING, tp_mod); 410 + end: 411 + mutex_unlock(&tracepoint_module_list_mutex); 412 + return ret; 413 + 414 + } 415 + EXPORT_SYMBOL_GPL(unregister_tracepoint_module_notifier); 416 + 417 + /* 418 + * Ensure the tracer unregistered the module's probes before the module 419 + * teardown is performed. Prevents leaks of probe and data pointers. 420 + */ 421 + static void tp_module_going_check_quiescent(struct tracepoint * const *begin, 422 + struct tracepoint * const *end) 423 + { 424 + struct tracepoint * const *iter; 425 + 426 + if (!begin) 427 + return; 428 + for (iter = begin; iter < end; iter++) 429 + WARN_ON_ONCE((*iter)->funcs); 392 430 } 393 431 394 432 static int tracepoint_module_coming(struct module *mod) ··· 371 479 */ 372 480 if (trace_module_has_bad_taint(mod)) 373 481 return 0; 374 - mutex_lock(&tracepoints_mutex); 482 + mutex_lock(&tracepoint_module_list_mutex); 375 483 tp_mod = kmalloc(sizeof(struct tp_module), GFP_KERNEL); 376 484 if (!tp_mod) { 377 485 ret = -ENOMEM; 378 486 goto end; 379 487 } 380 - tp_mod->num_tracepoints = mod->num_tracepoints; 381 - tp_mod->tracepoints_ptrs = mod->tracepoints_ptrs; 488 + tp_mod->mod = mod; 382 489 list_add_tail(&tp_mod->list, &tracepoint_module_list); 383 - tracepoint_update_probe_range(mod->tracepoints_ptrs, 384 - mod->tracepoints_ptrs + mod->num_tracepoints); 490 + blocking_notifier_call_chain(&tracepoint_notify_list, 491 + MODULE_STATE_COMING, tp_mod); 385 492 end: 386 - mutex_unlock(&tracepoints_mutex); 493 + mutex_unlock(&tracepoint_module_list_mutex); 387 494 return ret; 388 495 } 389 496 390 - static int tracepoint_module_going(struct module *mod) 497 + static void tracepoint_module_going(struct module *mod) 391 498 { 392 - struct tp_module *pos; 499 + struct tp_module *tp_mod; 393 500 394 501 if (!mod->num_tracepoints) 395 - return 0; 502 + return; 396 503 397 - mutex_lock(&tracepoints_mutex); 398 - tracepoint_update_probe_range(mod->tracepoints_ptrs, 399 - mod->tracepoints_ptrs + mod->num_tracepoints); 400 - list_for_each_entry(pos, &tracepoint_module_list, list) { 401 - if (pos->tracepoints_ptrs == mod->tracepoints_ptrs) { 402 - list_del(&pos->list); 403 - kfree(pos); 504 + mutex_lock(&tracepoint_module_list_mutex); 505 + list_for_each_entry(tp_mod, &tracepoint_module_list, list) { 506 + if (tp_mod->mod == mod) { 507 + blocking_notifier_call_chain(&tracepoint_notify_list, 508 + MODULE_STATE_GOING, tp_mod); 509 + list_del(&tp_mod->list); 510 + kfree(tp_mod); 511 + /* 512 + * Called the going notifier before checking for 513 + * quiescence. 514 + */ 515 + tp_module_going_check_quiescent(mod->tracepoints_ptrs, 516 + mod->tracepoints_ptrs + mod->num_tracepoints); 404 517 break; 405 518 } 406 519 } ··· 415 518 * flag on "going", in case a module taints the kernel only after being 416 519 * loaded. 417 520 */ 418 - mutex_unlock(&tracepoints_mutex); 419 - return 0; 521 + mutex_unlock(&tracepoint_module_list_mutex); 420 522 } 421 523 422 - int tracepoint_module_notify(struct notifier_block *self, 423 - unsigned long val, void *data) 524 + static int tracepoint_module_notify(struct notifier_block *self, 525 + unsigned long val, void *data) 424 526 { 425 527 struct module *mod = data; 426 528 int ret = 0; ··· 431 535 case MODULE_STATE_LIVE: 432 536 break; 433 537 case MODULE_STATE_GOING: 434 - ret = tracepoint_module_going(mod); 538 + tracepoint_module_going(mod); 539 + break; 540 + case MODULE_STATE_UNFORMED: 435 541 break; 436 542 } 437 543 return ret; 438 544 } 439 545 440 - struct notifier_block tracepoint_module_nb = { 546 + static struct notifier_block tracepoint_module_nb = { 441 547 .notifier_call = tracepoint_module_notify, 442 548 .priority = 0, 443 549 }; 444 550 445 - static int init_tracepoints(void) 551 + static __init int init_tracepoints(void) 446 552 { 447 - return register_module_notifier(&tracepoint_module_nb); 553 + int ret; 554 + 555 + ret = register_module_notifier(&tracepoint_module_nb); 556 + if (ret) 557 + pr_warning("Failed to register tracepoint module enter notifier\n"); 558 + 559 + return ret; 448 560 } 449 561 __initcall(init_tracepoints); 450 562 #endif /* CONFIG_MODULES */ 563 + 564 + static void for_each_tracepoint_range(struct tracepoint * const *begin, 565 + struct tracepoint * const *end, 566 + void (*fct)(struct tracepoint *tp, void *priv), 567 + void *priv) 568 + { 569 + struct tracepoint * const *iter; 570 + 571 + if (!begin) 572 + return; 573 + for (iter = begin; iter < end; iter++) 574 + fct(*iter, priv); 575 + } 576 + 577 + /** 578 + * for_each_kernel_tracepoint - iteration on all kernel tracepoints 579 + * @fct: callback 580 + * @priv: private data 581 + */ 582 + void for_each_kernel_tracepoint(void (*fct)(struct tracepoint *tp, void *priv), 583 + void *priv) 584 + { 585 + for_each_tracepoint_range(__start___tracepoints_ptrs, 586 + __stop___tracepoints_ptrs, fct, priv); 587 + } 588 + EXPORT_SYMBOL_GPL(for_each_kernel_tracepoint); 451 589 452 590 #ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS 453 591