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-v4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace

Pull tracing fixes from Steven Rostedt:
"Three minor updates

- Use the new GFP_RETRY_MAYFAIL to be more aggressive in allocating
memory for the ring buffer without causing OOMs

- Fix a memory leak in adding and removing instances

- Add __rcu annotation to be able to debug RCU usage of function
tracing a bit better"

* tag 'trace-v4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace:
trace: fix the errors caused by incompatible type of RCU variables
tracing: Fix kmemleak in instance_rmdir
tracing/ring_buffer: Try harder to allocate

+40 -26
+3 -3
include/linux/ftrace.h
··· 145 145 #ifdef CONFIG_DYNAMIC_FTRACE 146 146 /* The hash used to know what functions callbacks trace */ 147 147 struct ftrace_ops_hash { 148 - struct ftrace_hash *notrace_hash; 149 - struct ftrace_hash *filter_hash; 148 + struct ftrace_hash __rcu *notrace_hash; 149 + struct ftrace_hash __rcu *filter_hash; 150 150 struct mutex regex_lock; 151 151 }; 152 152 ··· 168 168 */ 169 169 struct ftrace_ops { 170 170 ftrace_func_t func; 171 - struct ftrace_ops *next; 171 + struct ftrace_ops __rcu *next; 172 172 unsigned long flags; 173 173 void *private; 174 174 ftrace_func_t saved_func;
+1 -1
include/linux/trace_events.h
··· 338 338 struct trace_event_file { 339 339 struct list_head list; 340 340 struct trace_event_call *event_call; 341 - struct event_filter *filter; 341 + struct event_filter __rcu *filter; 342 342 struct dentry *dir; 343 343 struct trace_array *tr; 344 344 struct trace_subsystem_dir *system;
+27 -14
kernel/trace/ftrace.c
··· 113 113 114 114 static DEFINE_MUTEX(ftrace_lock); 115 115 116 - static struct ftrace_ops *ftrace_ops_list __read_mostly = &ftrace_list_end; 116 + static struct ftrace_ops __rcu *ftrace_ops_list __read_mostly = &ftrace_list_end; 117 117 ftrace_func_t ftrace_trace_function __read_mostly = ftrace_stub; 118 118 static struct ftrace_ops global_ops; 119 119 ··· 169 169 170 170 mutex_lock(&ftrace_lock); 171 171 172 - for (ops = ftrace_ops_list; 173 - ops != &ftrace_list_end; ops = ops->next) 172 + for (ops = rcu_dereference_protected(ftrace_ops_list, 173 + lockdep_is_held(&ftrace_lock)); 174 + ops != &ftrace_list_end; 175 + ops = rcu_dereference_protected(ops->next, 176 + lockdep_is_held(&ftrace_lock))) 174 177 cnt++; 175 178 176 179 mutex_unlock(&ftrace_lock); ··· 278 275 * If there's only one ftrace_ops registered, the ftrace_ops_list 279 276 * will point to the ops we want. 280 277 */ 281 - set_function_trace_op = ftrace_ops_list; 278 + set_function_trace_op = rcu_dereference_protected(ftrace_ops_list, 279 + lockdep_is_held(&ftrace_lock)); 282 280 283 281 /* If there's no ftrace_ops registered, just call the stub function */ 284 - if (ftrace_ops_list == &ftrace_list_end) { 282 + if (set_function_trace_op == &ftrace_list_end) { 285 283 func = ftrace_stub; 286 284 287 285 /* ··· 290 286 * recursion safe and not dynamic and the arch supports passing ops, 291 287 * then have the mcount trampoline call the function directly. 292 288 */ 293 - } else if (ftrace_ops_list->next == &ftrace_list_end) { 289 + } else if (rcu_dereference_protected(ftrace_ops_list->next, 290 + lockdep_is_held(&ftrace_lock)) == &ftrace_list_end) { 294 291 func = ftrace_ops_get_list_func(ftrace_ops_list); 295 292 296 293 } else { ··· 353 348 return ftrace_trace_function == ftrace_ops_list_func; 354 349 } 355 350 356 - static void add_ftrace_ops(struct ftrace_ops **list, struct ftrace_ops *ops) 351 + static void add_ftrace_ops(struct ftrace_ops __rcu **list, 352 + struct ftrace_ops *ops) 357 353 { 358 - ops->next = *list; 354 + rcu_assign_pointer(ops->next, *list); 355 + 359 356 /* 360 357 * We are entering ops into the list but another 361 358 * CPU might be walking that list. We need to make sure ··· 367 360 rcu_assign_pointer(*list, ops); 368 361 } 369 362 370 - static int remove_ftrace_ops(struct ftrace_ops **list, struct ftrace_ops *ops) 363 + static int remove_ftrace_ops(struct ftrace_ops __rcu **list, 364 + struct ftrace_ops *ops) 371 365 { 372 366 struct ftrace_ops **p; 373 367 ··· 376 368 * If we are removing the last function, then simply point 377 369 * to the ftrace_stub. 378 370 */ 379 - if (*list == ops && ops->next == &ftrace_list_end) { 371 + if (rcu_dereference_protected(*list, 372 + lockdep_is_held(&ftrace_lock)) == ops && 373 + rcu_dereference_protected(ops->next, 374 + lockdep_is_held(&ftrace_lock)) == &ftrace_list_end) { 380 375 *list = &ftrace_list_end; 381 376 return 0; 382 377 } ··· 1580 1569 return 0; 1581 1570 #endif 1582 1571 1583 - hash.filter_hash = rcu_dereference_raw_notrace(ops->func_hash->filter_hash); 1584 - hash.notrace_hash = rcu_dereference_raw_notrace(ops->func_hash->notrace_hash); 1572 + rcu_assign_pointer(hash.filter_hash, ops->func_hash->filter_hash); 1573 + rcu_assign_pointer(hash.notrace_hash, ops->func_hash->notrace_hash); 1585 1574 1586 1575 if (hash_contains_ip(ip, &hash)) 1587 1576 ret = 1; ··· 2851 2840 * If there's no more ops registered with ftrace, run a 2852 2841 * sanity check to make sure all rec flags are cleared. 2853 2842 */ 2854 - if (ftrace_ops_list == &ftrace_list_end) { 2843 + if (rcu_dereference_protected(ftrace_ops_list, 2844 + lockdep_is_held(&ftrace_lock)) == &ftrace_list_end) { 2855 2845 struct ftrace_page *pg; 2856 2846 struct dyn_ftrace *rec; 2857 2847 ··· 6465 6453 if (ftrace_enabled) { 6466 6454 6467 6455 /* we are starting ftrace again */ 6468 - if (ftrace_ops_list != &ftrace_list_end) 6456 + if (rcu_dereference_protected(ftrace_ops_list, 6457 + lockdep_is_held(&ftrace_lock)) != &ftrace_list_end) 6469 6458 update_ftrace_function(); 6470 6459 6471 6460 ftrace_startup_sysctl();
+5 -5
kernel/trace/ring_buffer.c
··· 1136 1136 for (i = 0; i < nr_pages; i++) { 1137 1137 struct page *page; 1138 1138 /* 1139 - * __GFP_NORETRY flag makes sure that the allocation fails 1140 - * gracefully without invoking oom-killer and the system is 1141 - * not destabilized. 1139 + * __GFP_RETRY_MAYFAIL flag makes sure that the allocation fails 1140 + * gracefully without invoking oom-killer and the system is not 1141 + * destabilized. 1142 1142 */ 1143 1143 bpage = kzalloc_node(ALIGN(sizeof(*bpage), cache_line_size()), 1144 - GFP_KERNEL | __GFP_NORETRY, 1144 + GFP_KERNEL | __GFP_RETRY_MAYFAIL, 1145 1145 cpu_to_node(cpu)); 1146 1146 if (!bpage) 1147 1147 goto free_pages; ··· 1149 1149 list_add(&bpage->list, pages); 1150 1150 1151 1151 page = alloc_pages_node(cpu_to_node(cpu), 1152 - GFP_KERNEL | __GFP_NORETRY, 0); 1152 + GFP_KERNEL | __GFP_RETRY_MAYFAIL, 0); 1153 1153 if (!page) 1154 1154 goto free_pages; 1155 1155 bpage->page = page_address(page);
+1
kernel/trace/trace.c
··· 7774 7774 } 7775 7775 kfree(tr->topts); 7776 7776 7777 + free_cpumask_var(tr->tracing_cpumask); 7777 7778 kfree(tr->name); 7778 7779 kfree(tr); 7779 7780
+3 -3
kernel/trace/trace.h
··· 1210 1210 struct event_filter { 1211 1211 int n_preds; /* Number assigned */ 1212 1212 int a_preds; /* allocated */ 1213 - struct filter_pred *preds; 1214 - struct filter_pred *root; 1215 - char *filter_string; 1213 + struct filter_pred __rcu *preds; 1214 + struct filter_pred __rcu *root; 1215 + char *filter_string; 1216 1216 }; 1217 1217 1218 1218 struct event_subsystem {