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

Merge tag 'trace-fixes-3.11-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace

Pull tracing fixes from Steven Rostedt:
"Oleg Nesterov has been working hard in closing all the holes that can
lead to race conditions between deleting an event and accessing an
event debugfs file. This included a fix to the debugfs system (acked
by Greg Kroah-Hartman). We think that all the holes have been patched
and hopefully we don't find more. I haven't marked all of them for
stable because I need to examine them more to figure out how far back
some of the changes need to go.

Along the way, some other fixes have been made. Alexander Z Lam fixed
some logic where the wrong buffer was being modifed.

Andrew Vagin found a possible corruption for machines that actually
allocate cpumask, as a reference to one was being zeroed out by
mistake.

Dhaval Giani found a bad prototype when tracing is not configured.

And I not only had some changes to help Oleg, but also finally fixed a
long standing bug that Dave Jones and others have been hitting, where
a module unload and reload can cause the function tracing accounting
to get screwed up"

* tag 'trace-fixes-3.11-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace:
tracing: Fix reset of time stamps during trace_clock changes
tracing: Make TRACE_ITER_STOP_ON_FREE stop the correct buffer
tracing: Fix trace_dump_stack() proto when CONFIG_TRACING is not set
tracing: Fix fields of struct trace_iterator that are zeroed by mistake
tracing/uprobes: Fail to unregister if probe event files are in use
tracing/kprobes: Fail to unregister if probe event files are in use
tracing: Add comment to describe special break case in probe_remove_event_call()
tracing: trace_remove_event_call() should fail if call/file is in use
debugfs: debugfs_remove_recursive() must not rely on list_empty(d_subdirs)
ftrace: Check module functions being traced on reload
ftrace: Consolidate some duplicate code for updating ftrace ops
tracing: Change remove_event_file_dir() to clear "d_subdirs"->i_private
tracing: Introduce remove_event_file_dir()
tracing: Change f_start() to take event_mutex and verify i_private != NULL
tracing: Change event_filter_read/write to verify i_private != NULL
tracing: Change event_enable/disable_read() to verify i_private != NULL
tracing: Turn event/id->i_private into call->event.type

+305 -187
+23 -48
fs/debugfs/inode.c
··· 533 533 */ 534 534 void debugfs_remove_recursive(struct dentry *dentry) 535 535 { 536 - struct dentry *child; 537 - struct dentry *parent; 536 + struct dentry *child, *next, *parent; 538 537 539 538 if (IS_ERR_OR_NULL(dentry)) 540 539 return; ··· 543 544 return; 544 545 545 546 parent = dentry; 547 + down: 546 548 mutex_lock(&parent->d_inode->i_mutex); 549 + list_for_each_entry_safe(child, next, &parent->d_subdirs, d_u.d_child) { 550 + if (!debugfs_positive(child)) 551 + continue; 547 552 548 - while (1) { 549 - /* 550 - * When all dentries under "parent" has been removed, 551 - * walk up the tree until we reach our starting point. 552 - */ 553 - if (list_empty(&parent->d_subdirs)) { 554 - mutex_unlock(&parent->d_inode->i_mutex); 555 - if (parent == dentry) 556 - break; 557 - parent = parent->d_parent; 558 - mutex_lock(&parent->d_inode->i_mutex); 559 - } 560 - child = list_entry(parent->d_subdirs.next, struct dentry, 561 - d_u.d_child); 562 - next_sibling: 563 - 564 - /* 565 - * If "child" isn't empty, walk down the tree and 566 - * remove all its descendants first. 567 - */ 553 + /* perhaps simple_empty(child) makes more sense */ 568 554 if (!list_empty(&child->d_subdirs)) { 569 555 mutex_unlock(&parent->d_inode->i_mutex); 570 556 parent = child; 571 - mutex_lock(&parent->d_inode->i_mutex); 572 - continue; 557 + goto down; 573 558 } 574 - __debugfs_remove(child, parent); 575 - if (parent->d_subdirs.next == &child->d_u.d_child) { 576 - /* 577 - * Try the next sibling. 578 - */ 579 - if (child->d_u.d_child.next != &parent->d_subdirs) { 580 - child = list_entry(child->d_u.d_child.next, 581 - struct dentry, 582 - d_u.d_child); 583 - goto next_sibling; 584 - } 585 - 586 - /* 587 - * Avoid infinite loop if we fail to remove 588 - * one dentry. 589 - */ 590 - mutex_unlock(&parent->d_inode->i_mutex); 591 - break; 592 - } 593 - simple_release_fs(&debugfs_mount, &debugfs_mount_count); 559 + up: 560 + if (!__debugfs_remove(child, parent)) 561 + simple_release_fs(&debugfs_mount, &debugfs_mount_count); 594 562 } 595 563 596 - parent = dentry->d_parent; 597 - mutex_lock(&parent->d_inode->i_mutex); 598 - __debugfs_remove(dentry, parent); 599 564 mutex_unlock(&parent->d_inode->i_mutex); 600 - simple_release_fs(&debugfs_mount, &debugfs_mount_count); 565 + child = parent; 566 + parent = parent->d_parent; 567 + mutex_lock(&parent->d_inode->i_mutex); 568 + 569 + if (child != dentry) { 570 + next = list_entry(child->d_u.d_child.next, struct dentry, 571 + d_u.d_child); 572 + goto up; 573 + } 574 + 575 + if (!__debugfs_remove(child, parent)) 576 + simple_release_fs(&debugfs_mount, &debugfs_mount_count); 577 + mutex_unlock(&parent->d_inode->i_mutex); 601 578 } 602 579 EXPORT_SYMBOL_GPL(debugfs_remove_recursive); 603 580
+7 -5
include/linux/ftrace_event.h
··· 78 78 /* trace_seq for __print_flags() and __print_symbolic() etc. */ 79 79 struct trace_seq tmp_seq; 80 80 81 + cpumask_var_t started; 82 + 83 + /* it's true when current open file is snapshot */ 84 + bool snapshot; 85 + 81 86 /* The below is zeroed out in pipe_read */ 82 87 struct trace_seq seq; 83 88 struct trace_entry *ent; ··· 95 90 loff_t pos; 96 91 long idx; 97 92 98 - cpumask_var_t started; 99 - 100 - /* it's true when current open file is snapshot */ 101 - bool snapshot; 93 + /* All new field here will be zeroed out in pipe_read */ 102 94 }; 103 95 104 96 enum trace_iter_flags { ··· 334 332 const char *name, int offset, int size, 335 333 int is_signed, int filter_type); 336 334 extern int trace_add_event_call(struct ftrace_event_call *call); 337 - extern void trace_remove_event_call(struct ftrace_event_call *call); 335 + extern int trace_remove_event_call(struct ftrace_event_call *call); 338 336 339 337 #define is_signed_type(type) (((type)(-1)) < (type)1) 340 338
+1 -1
include/linux/kernel.h
··· 629 629 static inline void tracing_start(void) { } 630 630 static inline void tracing_stop(void) { } 631 631 static inline void ftrace_off_permanent(void) { } 632 - static inline void trace_dump_stack(void) { } 632 + static inline void trace_dump_stack(int skip) { } 633 633 634 634 static inline void tracing_on(void) { } 635 635 static inline void tracing_off(void) { }
+72 -15
kernel/trace/ftrace.c
··· 2169 2169 static unsigned long ftrace_update_cnt; 2170 2170 unsigned long ftrace_update_tot_cnt; 2171 2171 2172 - static int ops_traces_mod(struct ftrace_ops *ops) 2172 + static inline int ops_traces_mod(struct ftrace_ops *ops) 2173 2173 { 2174 - struct ftrace_hash *hash; 2174 + /* 2175 + * Filter_hash being empty will default to trace module. 2176 + * But notrace hash requires a test of individual module functions. 2177 + */ 2178 + return ftrace_hash_empty(ops->filter_hash) && 2179 + ftrace_hash_empty(ops->notrace_hash); 2180 + } 2175 2181 2176 - hash = ops->filter_hash; 2177 - return ftrace_hash_empty(hash); 2182 + /* 2183 + * Check if the current ops references the record. 2184 + * 2185 + * If the ops traces all functions, then it was already accounted for. 2186 + * If the ops does not trace the current record function, skip it. 2187 + * If the ops ignores the function via notrace filter, skip it. 2188 + */ 2189 + static inline bool 2190 + ops_references_rec(struct ftrace_ops *ops, struct dyn_ftrace *rec) 2191 + { 2192 + /* If ops isn't enabled, ignore it */ 2193 + if (!(ops->flags & FTRACE_OPS_FL_ENABLED)) 2194 + return 0; 2195 + 2196 + /* If ops traces all mods, we already accounted for it */ 2197 + if (ops_traces_mod(ops)) 2198 + return 0; 2199 + 2200 + /* The function must be in the filter */ 2201 + if (!ftrace_hash_empty(ops->filter_hash) && 2202 + !ftrace_lookup_ip(ops->filter_hash, rec->ip)) 2203 + return 0; 2204 + 2205 + /* If in notrace hash, we ignore it too */ 2206 + if (ftrace_lookup_ip(ops->notrace_hash, rec->ip)) 2207 + return 0; 2208 + 2209 + return 1; 2210 + } 2211 + 2212 + static int referenced_filters(struct dyn_ftrace *rec) 2213 + { 2214 + struct ftrace_ops *ops; 2215 + int cnt = 0; 2216 + 2217 + for (ops = ftrace_ops_list; ops != &ftrace_list_end; ops = ops->next) { 2218 + if (ops_references_rec(ops, rec)) 2219 + cnt++; 2220 + } 2221 + 2222 + return cnt; 2178 2223 } 2179 2224 2180 2225 static int ftrace_update_code(struct module *mod) ··· 2228 2183 struct dyn_ftrace *p; 2229 2184 cycle_t start, stop; 2230 2185 unsigned long ref = 0; 2186 + bool test = false; 2231 2187 int i; 2232 2188 2233 2189 /* ··· 2242 2196 2243 2197 for (ops = ftrace_ops_list; 2244 2198 ops != &ftrace_list_end; ops = ops->next) { 2245 - if (ops->flags & FTRACE_OPS_FL_ENABLED && 2246 - ops_traces_mod(ops)) 2247 - ref++; 2199 + if (ops->flags & FTRACE_OPS_FL_ENABLED) { 2200 + if (ops_traces_mod(ops)) 2201 + ref++; 2202 + else 2203 + test = true; 2204 + } 2248 2205 } 2249 2206 } 2250 2207 ··· 2257 2208 for (pg = ftrace_new_pgs; pg; pg = pg->next) { 2258 2209 2259 2210 for (i = 0; i < pg->index; i++) { 2211 + int cnt = ref; 2212 + 2260 2213 /* If something went wrong, bail without enabling anything */ 2261 2214 if (unlikely(ftrace_disabled)) 2262 2215 return -1; 2263 2216 2264 2217 p = &pg->records[i]; 2265 - p->flags = ref; 2218 + if (test) 2219 + cnt += referenced_filters(p); 2220 + p->flags = cnt; 2266 2221 2267 2222 /* 2268 2223 * Do the initial record conversion from mcount jump ··· 2286 2233 * conversion puts the module to the correct state, thus 2287 2234 * passing the ftrace_make_call check. 2288 2235 */ 2289 - if (ftrace_start_up && ref) { 2236 + if (ftrace_start_up && cnt) { 2290 2237 int failed = __ftrace_replace_code(p, 1); 2291 2238 if (failed) 2292 2239 ftrace_bug(failed, p->ip); ··· 3437 3384 return add_hash_entry(hash, ip); 3438 3385 } 3439 3386 3387 + static void ftrace_ops_update_code(struct ftrace_ops *ops) 3388 + { 3389 + if (ops->flags & FTRACE_OPS_FL_ENABLED && ftrace_enabled) 3390 + ftrace_run_update_code(FTRACE_UPDATE_CALLS); 3391 + } 3392 + 3440 3393 static int 3441 3394 ftrace_set_hash(struct ftrace_ops *ops, unsigned char *buf, int len, 3442 3395 unsigned long ip, int remove, int reset, int enable) ··· 3485 3426 3486 3427 mutex_lock(&ftrace_lock); 3487 3428 ret = ftrace_hash_move(ops, enable, orig_hash, hash); 3488 - if (!ret && ops->flags & FTRACE_OPS_FL_ENABLED 3489 - && ftrace_enabled) 3490 - ftrace_run_update_code(FTRACE_UPDATE_CALLS); 3429 + if (!ret) 3430 + ftrace_ops_update_code(ops); 3491 3431 3492 3432 mutex_unlock(&ftrace_lock); 3493 3433 ··· 3713 3655 mutex_lock(&ftrace_lock); 3714 3656 ret = ftrace_hash_move(iter->ops, filter_hash, 3715 3657 orig_hash, iter->hash); 3716 - if (!ret && (iter->ops->flags & FTRACE_OPS_FL_ENABLED) 3717 - && ftrace_enabled) 3718 - ftrace_run_update_code(FTRACE_UPDATE_CALLS); 3658 + if (!ret) 3659 + ftrace_ops_update_code(iter->ops); 3719 3660 3720 3661 mutex_unlock(&ftrace_lock); 3721 3662 }
+14 -13
kernel/trace/trace.c
··· 243 243 } 244 244 EXPORT_SYMBOL_GPL(filter_current_check_discard); 245 245 246 - cycle_t ftrace_now(int cpu) 246 + cycle_t buffer_ftrace_now(struct trace_buffer *buf, int cpu) 247 247 { 248 248 u64 ts; 249 249 250 250 /* Early boot up does not have a buffer yet */ 251 - if (!global_trace.trace_buffer.buffer) 251 + if (!buf->buffer) 252 252 return trace_clock_local(); 253 253 254 - ts = ring_buffer_time_stamp(global_trace.trace_buffer.buffer, cpu); 255 - ring_buffer_normalize_time_stamp(global_trace.trace_buffer.buffer, cpu, &ts); 254 + ts = ring_buffer_time_stamp(buf->buffer, cpu); 255 + ring_buffer_normalize_time_stamp(buf->buffer, cpu, &ts); 256 256 257 257 return ts; 258 + } 259 + 260 + cycle_t ftrace_now(int cpu) 261 + { 262 + return buffer_ftrace_now(&global_trace.trace_buffer, cpu); 258 263 } 259 264 260 265 /** ··· 1216 1211 /* Make sure all commits have finished */ 1217 1212 synchronize_sched(); 1218 1213 1219 - buf->time_start = ftrace_now(buf->cpu); 1214 + buf->time_start = buffer_ftrace_now(buf, buf->cpu); 1220 1215 1221 1216 for_each_online_cpu(cpu) 1222 1217 ring_buffer_reset_cpu(buffer, cpu); 1223 1218 1224 1219 ring_buffer_record_enable(buffer); 1225 - } 1226 - 1227 - void tracing_reset_current(int cpu) 1228 - { 1229 - tracing_reset(&global_trace.trace_buffer, cpu); 1230 1220 } 1231 1221 1232 1222 /* Must have trace_types_lock held */ ··· 4151 4151 memset(&iter->seq, 0, 4152 4152 sizeof(struct trace_iterator) - 4153 4153 offsetof(struct trace_iterator, seq)); 4154 + cpumask_clear(iter->started); 4154 4155 iter->pos = -1; 4155 4156 4156 4157 trace_event_read_lock(); ··· 4469 4468 4470 4469 /* disable tracing ? */ 4471 4470 if (trace_flags & TRACE_ITER_STOP_ON_FREE) 4472 - tracing_off(); 4471 + tracer_tracing_off(tr); 4473 4472 /* resize the ring buffer to 0 */ 4474 4473 tracing_resize_ring_buffer(tr, 0, RING_BUFFER_ALL_CPUS); 4475 4474 ··· 4634 4633 * New clock may not be consistent with the previous clock. 4635 4634 * Reset the buffer so that it doesn't have incomparable timestamps. 4636 4635 */ 4637 - tracing_reset_online_cpus(&global_trace.trace_buffer); 4636 + tracing_reset_online_cpus(&tr->trace_buffer); 4638 4637 4639 4638 #ifdef CONFIG_TRACER_MAX_TRACE 4640 4639 if (tr->flags & TRACE_ARRAY_FL_GLOBAL && tr->max_buffer.buffer) 4641 4640 ring_buffer_set_clock(tr->max_buffer.buffer, trace_clocks[i].func); 4642 - tracing_reset_online_cpus(&global_trace.max_buffer); 4641 + tracing_reset_online_cpus(&tr->max_buffer); 4643 4642 #endif 4644 4643 4645 4644 mutex_unlock(&trace_types_lock);
+129 -75
kernel/trace/trace_events.c
··· 409 409 mutex_unlock(&event_mutex); 410 410 } 411 411 412 - /* 413 - * Open and update trace_array ref count. 414 - * Must have the current trace_array passed to it. 415 - */ 416 - static int tracing_open_generic_file(struct inode *inode, struct file *filp) 412 + static void remove_subsystem(struct ftrace_subsystem_dir *dir) 417 413 { 418 - struct ftrace_event_file *file = inode->i_private; 419 - struct trace_array *tr = file->tr; 420 - int ret; 414 + if (!dir) 415 + return; 421 416 422 - if (trace_array_get(tr) < 0) 423 - return -ENODEV; 424 - 425 - ret = tracing_open_generic(inode, filp); 426 - if (ret < 0) 427 - trace_array_put(tr); 428 - return ret; 417 + if (!--dir->nr_events) { 418 + debugfs_remove_recursive(dir->entry); 419 + list_del(&dir->list); 420 + __put_system_dir(dir); 421 + } 429 422 } 430 423 431 - static int tracing_release_generic_file(struct inode *inode, struct file *filp) 424 + static void *event_file_data(struct file *filp) 432 425 { 433 - struct ftrace_event_file *file = inode->i_private; 434 - struct trace_array *tr = file->tr; 426 + return ACCESS_ONCE(file_inode(filp)->i_private); 427 + } 435 428 436 - trace_array_put(tr); 429 + static void remove_event_file_dir(struct ftrace_event_file *file) 430 + { 431 + struct dentry *dir = file->dir; 432 + struct dentry *child; 437 433 438 - return 0; 434 + if (dir) { 435 + spin_lock(&dir->d_lock); /* probably unneeded */ 436 + list_for_each_entry(child, &dir->d_subdirs, d_u.d_child) { 437 + if (child->d_inode) /* probably unneeded */ 438 + child->d_inode->i_private = NULL; 439 + } 440 + spin_unlock(&dir->d_lock); 441 + 442 + debugfs_remove_recursive(dir); 443 + } 444 + 445 + list_del(&file->list); 446 + remove_subsystem(file->system); 447 + kmem_cache_free(file_cachep, file); 439 448 } 440 449 441 450 /* ··· 688 679 event_enable_read(struct file *filp, char __user *ubuf, size_t cnt, 689 680 loff_t *ppos) 690 681 { 691 - struct ftrace_event_file *file = filp->private_data; 682 + struct ftrace_event_file *file; 683 + unsigned long flags; 692 684 char buf[4] = "0"; 693 685 694 - if (file->flags & FTRACE_EVENT_FL_ENABLED && 695 - !(file->flags & FTRACE_EVENT_FL_SOFT_DISABLED)) 686 + mutex_lock(&event_mutex); 687 + file = event_file_data(filp); 688 + if (likely(file)) 689 + flags = file->flags; 690 + mutex_unlock(&event_mutex); 691 + 692 + if (!file) 693 + return -ENODEV; 694 + 695 + if (flags & FTRACE_EVENT_FL_ENABLED && 696 + !(flags & FTRACE_EVENT_FL_SOFT_DISABLED)) 696 697 strcpy(buf, "1"); 697 698 698 - if (file->flags & FTRACE_EVENT_FL_SOFT_DISABLED || 699 - file->flags & FTRACE_EVENT_FL_SOFT_MODE) 699 + if (flags & FTRACE_EVENT_FL_SOFT_DISABLED || 700 + flags & FTRACE_EVENT_FL_SOFT_MODE) 700 701 strcat(buf, "*"); 701 702 702 703 strcat(buf, "\n"); ··· 718 699 event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt, 719 700 loff_t *ppos) 720 701 { 721 - struct ftrace_event_file *file = filp->private_data; 702 + struct ftrace_event_file *file; 722 703 unsigned long val; 723 704 int ret; 724 - 725 - if (!file) 726 - return -EINVAL; 727 705 728 706 ret = kstrtoul_from_user(ubuf, cnt, 10, &val); 729 707 if (ret) ··· 733 717 switch (val) { 734 718 case 0: 735 719 case 1: 720 + ret = -ENODEV; 736 721 mutex_lock(&event_mutex); 737 - ret = ftrace_event_enable_disable(file, val); 722 + file = event_file_data(filp); 723 + if (likely(file)) 724 + ret = ftrace_event_enable_disable(file, val); 738 725 mutex_unlock(&event_mutex); 739 726 break; 740 727 ··· 844 825 845 826 static void *f_next(struct seq_file *m, void *v, loff_t *pos) 846 827 { 847 - struct ftrace_event_call *call = m->private; 828 + struct ftrace_event_call *call = event_file_data(m->private); 848 829 struct list_head *common_head = &ftrace_common_fields; 849 830 struct list_head *head = trace_get_fields(call); 850 831 struct list_head *node = v; ··· 876 857 877 858 static int f_show(struct seq_file *m, void *v) 878 859 { 879 - struct ftrace_event_call *call = m->private; 860 + struct ftrace_event_call *call = event_file_data(m->private); 880 861 struct ftrace_event_field *field; 881 862 const char *array_descriptor; 882 863 ··· 929 910 void *p = (void *)FORMAT_HEADER; 930 911 loff_t l = 0; 931 912 913 + /* ->stop() is called even if ->start() fails */ 914 + mutex_lock(&event_mutex); 915 + if (!event_file_data(m->private)) 916 + return ERR_PTR(-ENODEV); 917 + 932 918 while (l < *pos && p) 933 919 p = f_next(m, p, &l); 934 920 ··· 942 918 943 919 static void f_stop(struct seq_file *m, void *p) 944 920 { 921 + mutex_unlock(&event_mutex); 945 922 } 946 923 947 924 static const struct seq_operations trace_format_seq_ops = { ··· 954 929 955 930 static int trace_format_open(struct inode *inode, struct file *file) 956 931 { 957 - struct ftrace_event_call *call = inode->i_private; 958 932 struct seq_file *m; 959 933 int ret; 960 934 ··· 962 938 return ret; 963 939 964 940 m = file->private_data; 965 - m->private = call; 941 + m->private = file; 966 942 967 943 return 0; 968 944 } ··· 970 946 static ssize_t 971 947 event_id_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) 972 948 { 973 - struct ftrace_event_call *call = filp->private_data; 949 + int id = (long)event_file_data(filp); 974 950 char buf[32]; 975 951 int len; 976 952 977 953 if (*ppos) 978 954 return 0; 979 955 980 - len = sprintf(buf, "%d\n", call->event.type); 956 + if (unlikely(!id)) 957 + return -ENODEV; 958 + 959 + len = sprintf(buf, "%d\n", id); 960 + 981 961 return simple_read_from_buffer(ubuf, cnt, ppos, buf, len); 982 962 } 983 963 ··· 989 961 event_filter_read(struct file *filp, char __user *ubuf, size_t cnt, 990 962 loff_t *ppos) 991 963 { 992 - struct ftrace_event_call *call = filp->private_data; 964 + struct ftrace_event_call *call; 993 965 struct trace_seq *s; 994 - int r; 966 + int r = -ENODEV; 995 967 996 968 if (*ppos) 997 969 return 0; 998 970 999 971 s = kmalloc(sizeof(*s), GFP_KERNEL); 972 + 1000 973 if (!s) 1001 974 return -ENOMEM; 1002 975 1003 976 trace_seq_init(s); 1004 977 1005 - print_event_filter(call, s); 1006 - r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len); 978 + mutex_lock(&event_mutex); 979 + call = event_file_data(filp); 980 + if (call) 981 + print_event_filter(call, s); 982 + mutex_unlock(&event_mutex); 983 + 984 + if (call) 985 + r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len); 1007 986 1008 987 kfree(s); 1009 988 ··· 1021 986 event_filter_write(struct file *filp, const char __user *ubuf, size_t cnt, 1022 987 loff_t *ppos) 1023 988 { 1024 - struct ftrace_event_call *call = filp->private_data; 989 + struct ftrace_event_call *call; 1025 990 char *buf; 1026 - int err; 991 + int err = -ENODEV; 1027 992 1028 993 if (cnt >= PAGE_SIZE) 1029 994 return -EINVAL; ··· 1038 1003 } 1039 1004 buf[cnt] = '\0'; 1040 1005 1041 - err = apply_event_filter(call, buf); 1006 + mutex_lock(&event_mutex); 1007 + call = event_file_data(filp); 1008 + if (call) 1009 + err = apply_event_filter(call, buf); 1010 + mutex_unlock(&event_mutex); 1011 + 1042 1012 free_page((unsigned long) buf); 1043 1013 if (err < 0) 1044 1014 return err; ··· 1265 1225 }; 1266 1226 1267 1227 static const struct file_operations ftrace_enable_fops = { 1268 - .open = tracing_open_generic_file, 1228 + .open = tracing_open_generic, 1269 1229 .read = event_enable_read, 1270 1230 .write = event_enable_write, 1271 - .release = tracing_release_generic_file, 1272 1231 .llseek = default_llseek, 1273 1232 }; 1274 1233 ··· 1279 1240 }; 1280 1241 1281 1242 static const struct file_operations ftrace_event_id_fops = { 1282 - .open = tracing_open_generic, 1283 1243 .read = event_id_read, 1284 1244 .llseek = default_llseek, 1285 1245 }; ··· 1526 1488 1527 1489 #ifdef CONFIG_PERF_EVENTS 1528 1490 if (call->event.type && call->class->reg) 1529 - trace_create_file("id", 0444, file->dir, call, 1530 - id); 1491 + trace_create_file("id", 0444, file->dir, 1492 + (void *)(long)call->event.type, id); 1531 1493 #endif 1532 1494 1533 1495 /* ··· 1552 1514 return 0; 1553 1515 } 1554 1516 1555 - static void remove_subsystem(struct ftrace_subsystem_dir *dir) 1556 - { 1557 - if (!dir) 1558 - return; 1559 - 1560 - if (!--dir->nr_events) { 1561 - debugfs_remove_recursive(dir->entry); 1562 - list_del(&dir->list); 1563 - __put_system_dir(dir); 1564 - } 1565 - } 1566 - 1567 1517 static void remove_event_from_tracers(struct ftrace_event_call *call) 1568 1518 { 1569 1519 struct ftrace_event_file *file; 1570 1520 struct trace_array *tr; 1571 1521 1572 1522 do_for_each_event_file_safe(tr, file) { 1573 - 1574 1523 if (file->event_call != call) 1575 1524 continue; 1576 1525 1577 - list_del(&file->list); 1578 - debugfs_remove_recursive(file->dir); 1579 - remove_subsystem(file->system); 1580 - kmem_cache_free(file_cachep, file); 1581 - 1526 + remove_event_file_dir(file); 1582 1527 /* 1583 1528 * The do_for_each_event_file_safe() is 1584 1529 * a double loop. After finding the call for this ··· 1713 1692 destroy_preds(call); 1714 1693 } 1715 1694 1716 - /* Remove an event_call */ 1717 - void trace_remove_event_call(struct ftrace_event_call *call) 1695 + static int probe_remove_event_call(struct ftrace_event_call *call) 1718 1696 { 1697 + struct trace_array *tr; 1698 + struct ftrace_event_file *file; 1699 + 1700 + #ifdef CONFIG_PERF_EVENTS 1701 + if (call->perf_refcount) 1702 + return -EBUSY; 1703 + #endif 1704 + do_for_each_event_file(tr, file) { 1705 + if (file->event_call != call) 1706 + continue; 1707 + /* 1708 + * We can't rely on ftrace_event_enable_disable(enable => 0) 1709 + * we are going to do, FTRACE_EVENT_FL_SOFT_MODE can suppress 1710 + * TRACE_REG_UNREGISTER. 1711 + */ 1712 + if (file->flags & FTRACE_EVENT_FL_ENABLED) 1713 + return -EBUSY; 1714 + /* 1715 + * The do_for_each_event_file_safe() is 1716 + * a double loop. After finding the call for this 1717 + * trace_array, we use break to jump to the next 1718 + * trace_array. 1719 + */ 1720 + break; 1721 + } while_for_each_event_file(); 1722 + 1723 + __trace_remove_event_call(call); 1724 + 1725 + return 0; 1726 + } 1727 + 1728 + /* Remove an event_call */ 1729 + int trace_remove_event_call(struct ftrace_event_call *call) 1730 + { 1731 + int ret; 1732 + 1719 1733 mutex_lock(&trace_types_lock); 1720 1734 mutex_lock(&event_mutex); 1721 1735 down_write(&trace_event_sem); 1722 - __trace_remove_event_call(call); 1736 + ret = probe_remove_event_call(call); 1723 1737 up_write(&trace_event_sem); 1724 1738 mutex_unlock(&event_mutex); 1725 1739 mutex_unlock(&trace_types_lock); 1740 + 1741 + return ret; 1726 1742 } 1727 1743 1728 1744 #define for_each_event(event, start, end) \ ··· 2328 2270 { 2329 2271 struct ftrace_event_file *file, *next; 2330 2272 2331 - list_for_each_entry_safe(file, next, &tr->events, list) { 2332 - list_del(&file->list); 2333 - debugfs_remove_recursive(file->dir); 2334 - remove_subsystem(file->system); 2335 - kmem_cache_free(file_cachep, file); 2336 - } 2273 + list_for_each_entry_safe(file, next, &tr->events, list) 2274 + remove_event_file_dir(file); 2337 2275 } 2338 2276 2339 2277 static void
+6 -11
kernel/trace/trace_events_filter.c
··· 637 637 free_page((unsigned long) buf); 638 638 } 639 639 640 + /* caller must hold event_mutex */ 640 641 void print_event_filter(struct ftrace_event_call *call, struct trace_seq *s) 641 642 { 642 - struct event_filter *filter; 643 + struct event_filter *filter = call->filter; 643 644 644 - mutex_lock(&event_mutex); 645 - filter = call->filter; 646 645 if (filter && filter->filter_string) 647 646 trace_seq_printf(s, "%s\n", filter->filter_string); 648 647 else 649 648 trace_seq_puts(s, "none\n"); 650 - mutex_unlock(&event_mutex); 651 649 } 652 650 653 651 void print_subsystem_event_filter(struct event_subsystem *system, ··· 1839 1841 return err; 1840 1842 } 1841 1843 1844 + /* caller must hold event_mutex */ 1842 1845 int apply_event_filter(struct ftrace_event_call *call, char *filter_string) 1843 1846 { 1844 1847 struct event_filter *filter; 1845 - int err = 0; 1846 - 1847 - mutex_lock(&event_mutex); 1848 + int err; 1848 1849 1849 1850 if (!strcmp(strstrip(filter_string), "0")) { 1850 1851 filter_disable(call); 1851 1852 filter = call->filter; 1852 1853 if (!filter) 1853 - goto out_unlock; 1854 + return 0; 1854 1855 RCU_INIT_POINTER(call->filter, NULL); 1855 1856 /* Make sure the filter is not being used */ 1856 1857 synchronize_sched(); 1857 1858 __free_filter(filter); 1858 - goto out_unlock; 1859 + return 0; 1859 1860 } 1860 1861 1861 1862 err = create_filter(call, filter_string, true, &filter); ··· 1881 1884 __free_filter(tmp); 1882 1885 } 1883 1886 } 1884 - out_unlock: 1885 - mutex_unlock(&event_mutex); 1886 1887 1887 1888 return err; 1888 1889 }
+15 -6
kernel/trace/trace_kprobe.c
··· 95 95 } 96 96 97 97 static int register_probe_event(struct trace_probe *tp); 98 - static void unregister_probe_event(struct trace_probe *tp); 98 + static int unregister_probe_event(struct trace_probe *tp); 99 99 100 100 static DEFINE_MUTEX(probe_lock); 101 101 static LIST_HEAD(probe_list); ··· 351 351 if (trace_probe_is_enabled(tp)) 352 352 return -EBUSY; 353 353 354 + /* Will fail if probe is being used by ftrace or perf */ 355 + if (unregister_probe_event(tp)) 356 + return -EBUSY; 357 + 354 358 __unregister_trace_probe(tp); 355 359 list_del(&tp->list); 356 - unregister_probe_event(tp); 357 360 358 361 return 0; 359 362 } ··· 635 632 /* TODO: Use batch unregistration */ 636 633 while (!list_empty(&probe_list)) { 637 634 tp = list_entry(probe_list.next, struct trace_probe, list); 638 - unregister_trace_probe(tp); 635 + ret = unregister_trace_probe(tp); 636 + if (ret) 637 + goto end; 639 638 free_trace_probe(tp); 640 639 } 641 640 ··· 1252 1247 return ret; 1253 1248 } 1254 1249 1255 - static void unregister_probe_event(struct trace_probe *tp) 1250 + static int unregister_probe_event(struct trace_probe *tp) 1256 1251 { 1252 + int ret; 1253 + 1257 1254 /* tp->event is unregistered in trace_remove_event_call() */ 1258 - trace_remove_event_call(&tp->call); 1259 - kfree(tp->call.print_fmt); 1255 + ret = trace_remove_event_call(&tp->call); 1256 + if (!ret) 1257 + kfree(tp->call.print_fmt); 1258 + return ret; 1260 1259 } 1261 1260 1262 1261 /* Make a debugfs interface for controlling probe points */
+38 -13
kernel/trace/trace_uprobe.c
··· 70 70 (sizeof(struct probe_arg) * (n))) 71 71 72 72 static int register_uprobe_event(struct trace_uprobe *tu); 73 - static void unregister_uprobe_event(struct trace_uprobe *tu); 73 + static int unregister_uprobe_event(struct trace_uprobe *tu); 74 74 75 75 static DEFINE_MUTEX(uprobe_lock); 76 76 static LIST_HEAD(uprobe_list); ··· 164 164 } 165 165 166 166 /* Unregister a trace_uprobe and probe_event: call with locking uprobe_lock */ 167 - static void unregister_trace_uprobe(struct trace_uprobe *tu) 167 + static int unregister_trace_uprobe(struct trace_uprobe *tu) 168 168 { 169 + int ret; 170 + 171 + ret = unregister_uprobe_event(tu); 172 + if (ret) 173 + return ret; 174 + 169 175 list_del(&tu->list); 170 - unregister_uprobe_event(tu); 171 176 free_trace_uprobe(tu); 177 + return 0; 172 178 } 173 179 174 180 /* Register a trace_uprobe and probe_event */ ··· 187 181 188 182 /* register as an event */ 189 183 old_tp = find_probe_event(tu->call.name, tu->call.class->system); 190 - if (old_tp) 184 + if (old_tp) { 191 185 /* delete old event */ 192 - unregister_trace_uprobe(old_tp); 186 + ret = unregister_trace_uprobe(old_tp); 187 + if (ret) 188 + goto end; 189 + } 193 190 194 191 ret = register_uprobe_event(tu); 195 192 if (ret) { ··· 265 256 group = UPROBE_EVENT_SYSTEM; 266 257 267 258 if (is_delete) { 259 + int ret; 260 + 268 261 if (!event) { 269 262 pr_info("Delete command needs an event name.\n"); 270 263 return -EINVAL; ··· 280 269 return -ENOENT; 281 270 } 282 271 /* delete an event */ 283 - unregister_trace_uprobe(tu); 272 + ret = unregister_trace_uprobe(tu); 284 273 mutex_unlock(&uprobe_lock); 285 - return 0; 274 + return ret; 286 275 } 287 276 288 277 if (argc < 2) { ··· 419 408 return ret; 420 409 } 421 410 422 - static void cleanup_all_probes(void) 411 + static int cleanup_all_probes(void) 423 412 { 424 413 struct trace_uprobe *tu; 414 + int ret = 0; 425 415 426 416 mutex_lock(&uprobe_lock); 427 417 while (!list_empty(&uprobe_list)) { 428 418 tu = list_entry(uprobe_list.next, struct trace_uprobe, list); 429 - unregister_trace_uprobe(tu); 419 + ret = unregister_trace_uprobe(tu); 420 + if (ret) 421 + break; 430 422 } 431 423 mutex_unlock(&uprobe_lock); 424 + return ret; 432 425 } 433 426 434 427 /* Probes listing interfaces */ ··· 477 462 478 463 static int probes_open(struct inode *inode, struct file *file) 479 464 { 480 - if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) 481 - cleanup_all_probes(); 465 + int ret; 466 + 467 + if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) { 468 + ret = cleanup_all_probes(); 469 + if (ret) 470 + return ret; 471 + } 482 472 483 473 return seq_open(file, &probes_seq_op); 484 474 } ··· 988 968 return ret; 989 969 } 990 970 991 - static void unregister_uprobe_event(struct trace_uprobe *tu) 971 + static int unregister_uprobe_event(struct trace_uprobe *tu) 992 972 { 973 + int ret; 974 + 993 975 /* tu->event is unregistered in trace_remove_event_call() */ 994 - trace_remove_event_call(&tu->call); 976 + ret = trace_remove_event_call(&tu->call); 977 + if (ret) 978 + return ret; 995 979 kfree(tu->call.print_fmt); 996 980 tu->call.print_fmt = NULL; 981 + return 0; 997 982 } 998 983 999 984 /* Make a trace interface for controling probe points */