aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/ftrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace/ftrace.c')
-rw-r--r--kernel/trace/ftrace.c233
1 files changed, 73 insertions, 160 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 8c804e24f96f..37ba67e33265 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -225,7 +225,11 @@ static void ftrace_update_pid_func(void)
225 if (ftrace_trace_function == ftrace_stub) 225 if (ftrace_trace_function == ftrace_stub)
226 return; 226 return;
227 227
228#ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
228 func = ftrace_trace_function; 229 func = ftrace_trace_function;
230#else
231 func = __ftrace_trace_function;
232#endif
229 233
230 if (ftrace_pid_trace) { 234 if (ftrace_pid_trace) {
231 set_ftrace_pid_function(func); 235 set_ftrace_pid_function(func);
@@ -1074,14 +1078,9 @@ static void ftrace_replace_code(int enable)
1074 failed = __ftrace_replace_code(rec, enable); 1078 failed = __ftrace_replace_code(rec, enable);
1075 if (failed) { 1079 if (failed) {
1076 rec->flags |= FTRACE_FL_FAILED; 1080 rec->flags |= FTRACE_FL_FAILED;
1077 if ((system_state == SYSTEM_BOOTING) || 1081 ftrace_bug(failed, rec->ip);
1078 !core_kernel_text(rec->ip)) { 1082 /* Stop processing */
1079 ftrace_free_rec(rec); 1083 return;
1080 } else {
1081 ftrace_bug(failed, rec->ip);
1082 /* Stop processing */
1083 return;
1084 }
1085 } 1084 }
1086 } while_for_each_ftrace_rec(); 1085 } while_for_each_ftrace_rec();
1087} 1086}
@@ -1323,11 +1322,10 @@ static int __init ftrace_dyn_table_alloc(unsigned long num_to_init)
1323 1322
1324enum { 1323enum {
1325 FTRACE_ITER_FILTER = (1 << 0), 1324 FTRACE_ITER_FILTER = (1 << 0),
1326 FTRACE_ITER_CONT = (1 << 1), 1325 FTRACE_ITER_NOTRACE = (1 << 1),
1327 FTRACE_ITER_NOTRACE = (1 << 2), 1326 FTRACE_ITER_FAILURES = (1 << 2),
1328 FTRACE_ITER_FAILURES = (1 << 3), 1327 FTRACE_ITER_PRINTALL = (1 << 3),
1329 FTRACE_ITER_PRINTALL = (1 << 4), 1328 FTRACE_ITER_HASH = (1 << 4),
1330 FTRACE_ITER_HASH = (1 << 5),
1331}; 1329};
1332 1330
1333#define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */ 1331#define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */
@@ -1337,8 +1335,7 @@ struct ftrace_iterator {
1337 int hidx; 1335 int hidx;
1338 int idx; 1336 int idx;
1339 unsigned flags; 1337 unsigned flags;
1340 unsigned char buffer[FTRACE_BUFF_MAX+1]; 1338 struct trace_parser parser;
1341 unsigned buffer_idx;
1342}; 1339};
1343 1340
1344static void * 1341static void *
@@ -1407,7 +1404,7 @@ static int t_hash_show(struct seq_file *m, void *v)
1407 if (rec->ops->print) 1404 if (rec->ops->print)
1408 return rec->ops->print(m, rec->ip, rec->ops, rec->data); 1405 return rec->ops->print(m, rec->ip, rec->ops, rec->data);
1409 1406
1410 seq_printf(m, "%pf:%pf", (void *)rec->ip, (void *)rec->ops->func); 1407 seq_printf(m, "%ps:%ps", (void *)rec->ip, (void *)rec->ops->func);
1411 1408
1412 if (rec->data) 1409 if (rec->data)
1413 seq_printf(m, ":%p", rec->data); 1410 seq_printf(m, ":%p", rec->data);
@@ -1517,12 +1514,12 @@ static int t_show(struct seq_file *m, void *v)
1517 if (!rec) 1514 if (!rec)
1518 return 0; 1515 return 0;
1519 1516
1520 seq_printf(m, "%pf\n", (void *)rec->ip); 1517 seq_printf(m, "%ps\n", (void *)rec->ip);
1521 1518
1522 return 0; 1519 return 0;
1523} 1520}
1524 1521
1525static struct seq_operations show_ftrace_seq_ops = { 1522static const struct seq_operations show_ftrace_seq_ops = {
1526 .start = t_start, 1523 .start = t_start,
1527 .next = t_next, 1524 .next = t_next,
1528 .stop = t_stop, 1525 .stop = t_stop,
@@ -1604,6 +1601,11 @@ ftrace_regex_open(struct inode *inode, struct file *file, int enable)
1604 if (!iter) 1601 if (!iter)
1605 return -ENOMEM; 1602 return -ENOMEM;
1606 1603
1604 if (trace_parser_get_init(&iter->parser, FTRACE_BUFF_MAX)) {
1605 kfree(iter);
1606 return -ENOMEM;
1607 }
1608
1607 mutex_lock(&ftrace_regex_lock); 1609 mutex_lock(&ftrace_regex_lock);
1608 if ((file->f_mode & FMODE_WRITE) && 1610 if ((file->f_mode & FMODE_WRITE) &&
1609 (file->f_flags & O_TRUNC)) 1611 (file->f_flags & O_TRUNC))
@@ -1618,8 +1620,10 @@ ftrace_regex_open(struct inode *inode, struct file *file, int enable)
1618 if (!ret) { 1620 if (!ret) {
1619 struct seq_file *m = file->private_data; 1621 struct seq_file *m = file->private_data;
1620 m->private = iter; 1622 m->private = iter;
1621 } else 1623 } else {
1624 trace_parser_put(&iter->parser);
1622 kfree(iter); 1625 kfree(iter);
1626 }
1623 } else 1627 } else
1624 file->private_data = iter; 1628 file->private_data = iter;
1625 mutex_unlock(&ftrace_regex_lock); 1629 mutex_unlock(&ftrace_regex_lock);
@@ -2059,9 +2063,9 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
2059 int i, len = 0; 2063 int i, len = 0;
2060 char *search; 2064 char *search;
2061 2065
2062 if (glob && (strcmp(glob, "*") || !strlen(glob))) 2066 if (glob && (strcmp(glob, "*") == 0 || !strlen(glob)))
2063 glob = NULL; 2067 glob = NULL;
2064 else { 2068 else if (glob) {
2065 int not; 2069 int not;
2066 2070
2067 type = ftrace_setup_glob(glob, strlen(glob), &search, &not); 2071 type = ftrace_setup_glob(glob, strlen(glob), &search, &not);
@@ -2196,11 +2200,10 @@ ftrace_regex_write(struct file *file, const char __user *ubuf,
2196 size_t cnt, loff_t *ppos, int enable) 2200 size_t cnt, loff_t *ppos, int enable)
2197{ 2201{
2198 struct ftrace_iterator *iter; 2202 struct ftrace_iterator *iter;
2199 char ch; 2203 struct trace_parser *parser;
2200 size_t read = 0; 2204 ssize_t ret, read;
2201 ssize_t ret;
2202 2205
2203 if (!cnt || cnt < 0) 2206 if (!cnt)
2204 return 0; 2207 return 0;
2205 2208
2206 mutex_lock(&ftrace_regex_lock); 2209 mutex_lock(&ftrace_regex_lock);
@@ -2211,72 +2214,23 @@ ftrace_regex_write(struct file *file, const char __user *ubuf,
2211 } else 2214 } else
2212 iter = file->private_data; 2215 iter = file->private_data;
2213 2216
2214 if (!*ppos) { 2217 parser = &iter->parser;
2215 iter->flags &= ~FTRACE_ITER_CONT; 2218 read = trace_get_user(parser, ubuf, cnt, ppos);
2216 iter->buffer_idx = 0;
2217 }
2218
2219 ret = get_user(ch, ubuf++);
2220 if (ret)
2221 goto out;
2222 read++;
2223 cnt--;
2224
2225 /*
2226 * If the parser haven't finished with the last write,
2227 * continue reading the user input without skipping spaces.
2228 */
2229 if (!(iter->flags & FTRACE_ITER_CONT)) {
2230 /* skip white space */
2231 while (cnt && isspace(ch)) {
2232 ret = get_user(ch, ubuf++);
2233 if (ret)
2234 goto out;
2235 read++;
2236 cnt--;
2237 }
2238
2239 /* only spaces were written */
2240 if (isspace(ch)) {
2241 *ppos += read;
2242 ret = read;
2243 goto out;
2244 }
2245
2246 iter->buffer_idx = 0;
2247 }
2248 2219
2249 while (cnt && !isspace(ch)) { 2220 if (read >= 0 && trace_parser_loaded(parser) &&
2250 if (iter->buffer_idx < FTRACE_BUFF_MAX) 2221 !trace_parser_cont(parser)) {
2251 iter->buffer[iter->buffer_idx++] = ch; 2222 ret = ftrace_process_regex(parser->buffer,
2252 else { 2223 parser->idx, enable);
2253 ret = -EINVAL;
2254 goto out;
2255 }
2256 ret = get_user(ch, ubuf++);
2257 if (ret) 2224 if (ret)
2258 goto out; 2225 goto out;
2259 read++;
2260 cnt--;
2261 }
2262 2226
2263 if (isspace(ch)) { 2227 trace_parser_clear(parser);
2264 iter->buffer[iter->buffer_idx] = 0;
2265 ret = ftrace_process_regex(iter->buffer,
2266 iter->buffer_idx, enable);
2267 if (ret)
2268 goto out;
2269 iter->buffer_idx = 0;
2270 } else {
2271 iter->flags |= FTRACE_ITER_CONT;
2272 iter->buffer[iter->buffer_idx++] = ch;
2273 } 2228 }
2274 2229
2275 *ppos += read;
2276 ret = read; 2230 ret = read;
2277 out:
2278 mutex_unlock(&ftrace_regex_lock);
2279 2231
2232 mutex_unlock(&ftrace_regex_lock);
2233out:
2280 return ret; 2234 return ret;
2281} 2235}
2282 2236
@@ -2381,6 +2335,7 @@ ftrace_regex_release(struct inode *inode, struct file *file, int enable)
2381{ 2335{
2382 struct seq_file *m = (struct seq_file *)file->private_data; 2336 struct seq_file *m = (struct seq_file *)file->private_data;
2383 struct ftrace_iterator *iter; 2337 struct ftrace_iterator *iter;
2338 struct trace_parser *parser;
2384 2339
2385 mutex_lock(&ftrace_regex_lock); 2340 mutex_lock(&ftrace_regex_lock);
2386 if (file->f_mode & FMODE_READ) { 2341 if (file->f_mode & FMODE_READ) {
@@ -2390,9 +2345,10 @@ ftrace_regex_release(struct inode *inode, struct file *file, int enable)
2390 } else 2345 } else
2391 iter = file->private_data; 2346 iter = file->private_data;
2392 2347
2393 if (iter->buffer_idx) { 2348 parser = &iter->parser;
2394 iter->buffer[iter->buffer_idx] = 0; 2349 if (trace_parser_loaded(parser)) {
2395 ftrace_match_records(iter->buffer, iter->buffer_idx, enable); 2350 parser->buffer[parser->idx] = 0;
2351 ftrace_match_records(parser->buffer, parser->idx, enable);
2396 } 2352 }
2397 2353
2398 mutex_lock(&ftrace_lock); 2354 mutex_lock(&ftrace_lock);
@@ -2400,7 +2356,9 @@ ftrace_regex_release(struct inode *inode, struct file *file, int enable)
2400 ftrace_run_update_code(FTRACE_ENABLE_CALLS); 2356 ftrace_run_update_code(FTRACE_ENABLE_CALLS);
2401 mutex_unlock(&ftrace_lock); 2357 mutex_unlock(&ftrace_lock);
2402 2358
2359 trace_parser_put(parser);
2403 kfree(iter); 2360 kfree(iter);
2361
2404 mutex_unlock(&ftrace_regex_lock); 2362 mutex_unlock(&ftrace_regex_lock);
2405 return 0; 2363 return 0;
2406} 2364}
@@ -2457,11 +2415,9 @@ unsigned long ftrace_graph_funcs[FTRACE_GRAPH_MAX_FUNCS] __read_mostly;
2457static void * 2415static void *
2458__g_next(struct seq_file *m, loff_t *pos) 2416__g_next(struct seq_file *m, loff_t *pos)
2459{ 2417{
2460 unsigned long *array = m->private;
2461
2462 if (*pos >= ftrace_graph_count) 2418 if (*pos >= ftrace_graph_count)
2463 return NULL; 2419 return NULL;
2464 return &array[*pos]; 2420 return &ftrace_graph_funcs[*pos];
2465} 2421}
2466 2422
2467static void * 2423static void *
@@ -2499,12 +2455,12 @@ static int g_show(struct seq_file *m, void *v)
2499 return 0; 2455 return 0;
2500 } 2456 }
2501 2457
2502 seq_printf(m, "%pf\n", v); 2458 seq_printf(m, "%ps\n", (void *)*ptr);
2503 2459
2504 return 0; 2460 return 0;
2505} 2461}
2506 2462
2507static struct seq_operations ftrace_graph_seq_ops = { 2463static const struct seq_operations ftrace_graph_seq_ops = {
2508 .start = g_start, 2464 .start = g_start,
2509 .next = g_next, 2465 .next = g_next,
2510 .stop = g_stop, 2466 .stop = g_stop,
@@ -2525,16 +2481,10 @@ ftrace_graph_open(struct inode *inode, struct file *file)
2525 ftrace_graph_count = 0; 2481 ftrace_graph_count = 0;
2526 memset(ftrace_graph_funcs, 0, sizeof(ftrace_graph_funcs)); 2482 memset(ftrace_graph_funcs, 0, sizeof(ftrace_graph_funcs));
2527 } 2483 }
2484 mutex_unlock(&graph_lock);
2528 2485
2529 if (file->f_mode & FMODE_READ) { 2486 if (file->f_mode & FMODE_READ)
2530 ret = seq_open(file, &ftrace_graph_seq_ops); 2487 ret = seq_open(file, &ftrace_graph_seq_ops);
2531 if (!ret) {
2532 struct seq_file *m = file->private_data;
2533 m->private = ftrace_graph_funcs;
2534 }
2535 } else
2536 file->private_data = ftrace_graph_funcs;
2537 mutex_unlock(&graph_lock);
2538 2488
2539 return ret; 2489 return ret;
2540} 2490}
@@ -2602,12 +2552,8 @@ static ssize_t
2602ftrace_graph_write(struct file *file, const char __user *ubuf, 2552ftrace_graph_write(struct file *file, const char __user *ubuf,
2603 size_t cnt, loff_t *ppos) 2553 size_t cnt, loff_t *ppos)
2604{ 2554{
2605 unsigned char buffer[FTRACE_BUFF_MAX+1]; 2555 struct trace_parser parser;
2606 unsigned long *array; 2556 ssize_t read, ret;
2607 size_t read = 0;
2608 ssize_t ret;
2609 int index = 0;
2610 char ch;
2611 2557
2612 if (!cnt || cnt < 0) 2558 if (!cnt || cnt < 0)
2613 return 0; 2559 return 0;
@@ -2616,60 +2562,31 @@ ftrace_graph_write(struct file *file, const char __user *ubuf,
2616 2562
2617 if (ftrace_graph_count >= FTRACE_GRAPH_MAX_FUNCS) { 2563 if (ftrace_graph_count >= FTRACE_GRAPH_MAX_FUNCS) {
2618 ret = -EBUSY; 2564 ret = -EBUSY;
2619 goto out; 2565 goto out_unlock;
2620 } 2566 }
2621 2567
2622 if (file->f_mode & FMODE_READ) { 2568 if (trace_parser_get_init(&parser, FTRACE_BUFF_MAX)) {
2623 struct seq_file *m = file->private_data; 2569 ret = -ENOMEM;
2624 array = m->private; 2570 goto out_unlock;
2625 } else
2626 array = file->private_data;
2627
2628 ret = get_user(ch, ubuf++);
2629 if (ret)
2630 goto out;
2631 read++;
2632 cnt--;
2633
2634 /* skip white space */
2635 while (cnt && isspace(ch)) {
2636 ret = get_user(ch, ubuf++);
2637 if (ret)
2638 goto out;
2639 read++;
2640 cnt--;
2641 } 2571 }
2642 2572
2643 if (isspace(ch)) { 2573 read = trace_get_user(&parser, ubuf, cnt, ppos);
2644 *ppos += read;
2645 ret = read;
2646 goto out;
2647 }
2648 2574
2649 while (cnt && !isspace(ch)) { 2575 if (read >= 0 && trace_parser_loaded((&parser))) {
2650 if (index < FTRACE_BUFF_MAX) 2576 parser.buffer[parser.idx] = 0;
2651 buffer[index++] = ch; 2577
2652 else { 2578 /* we allow only one expression at a time */
2653 ret = -EINVAL; 2579 ret = ftrace_set_func(ftrace_graph_funcs, &ftrace_graph_count,
2654 goto out; 2580 parser.buffer);
2655 }
2656 ret = get_user(ch, ubuf++);
2657 if (ret) 2581 if (ret)
2658 goto out; 2582 goto out_free;
2659 read++;
2660 cnt--;
2661 } 2583 }
2662 buffer[index] = 0;
2663
2664 /* we allow only one expression at a time */
2665 ret = ftrace_set_func(array, &ftrace_graph_count, buffer);
2666 if (ret)
2667 goto out;
2668
2669 file->f_pos += read;
2670 2584
2671 ret = read; 2585 ret = read;
2672 out: 2586
2587out_free:
2588 trace_parser_put(&parser);
2589out_unlock:
2673 mutex_unlock(&graph_lock); 2590 mutex_unlock(&graph_lock);
2674 2591
2675 return ret; 2592 return ret;
@@ -2740,19 +2657,17 @@ static int ftrace_convert_nops(struct module *mod,
2740} 2657}
2741 2658
2742#ifdef CONFIG_MODULES 2659#ifdef CONFIG_MODULES
2743void ftrace_release(void *start, void *end) 2660void ftrace_release_mod(struct module *mod)
2744{ 2661{
2745 struct dyn_ftrace *rec; 2662 struct dyn_ftrace *rec;
2746 struct ftrace_page *pg; 2663 struct ftrace_page *pg;
2747 unsigned long s = (unsigned long)start;
2748 unsigned long e = (unsigned long)end;
2749 2664
2750 if (ftrace_disabled || !start || start == end) 2665 if (ftrace_disabled)
2751 return; 2666 return;
2752 2667
2753 mutex_lock(&ftrace_lock); 2668 mutex_lock(&ftrace_lock);
2754 do_for_each_ftrace_rec(pg, rec) { 2669 do_for_each_ftrace_rec(pg, rec) {
2755 if ((rec->ip >= s) && (rec->ip < e)) { 2670 if (within_module_core(rec->ip, mod)) {
2756 /* 2671 /*
2757 * rec->ip is changed in ftrace_free_rec() 2672 * rec->ip is changed in ftrace_free_rec()
2758 * It should not between s and e if record was freed. 2673 * It should not between s and e if record was freed.
@@ -2784,9 +2699,7 @@ static int ftrace_module_notify(struct notifier_block *self,
2784 mod->num_ftrace_callsites); 2699 mod->num_ftrace_callsites);
2785 break; 2700 break;
2786 case MODULE_STATE_GOING: 2701 case MODULE_STATE_GOING:
2787 ftrace_release(mod->ftrace_callsites, 2702 ftrace_release_mod(mod);
2788 mod->ftrace_callsites +
2789 mod->num_ftrace_callsites);
2790 break; 2703 break;
2791 } 2704 }
2792 2705
@@ -3100,7 +3013,7 @@ int unregister_ftrace_function(struct ftrace_ops *ops)
3100 3013
3101int 3014int
3102ftrace_enable_sysctl(struct ctl_table *table, int write, 3015ftrace_enable_sysctl(struct ctl_table *table, int write,
3103 struct file *file, void __user *buffer, size_t *lenp, 3016 void __user *buffer, size_t *lenp,
3104 loff_t *ppos) 3017 loff_t *ppos)
3105{ 3018{
3106 int ret; 3019 int ret;
@@ -3110,7 +3023,7 @@ ftrace_enable_sysctl(struct ctl_table *table, int write,
3110 3023
3111 mutex_lock(&ftrace_lock); 3024 mutex_lock(&ftrace_lock);
3112 3025
3113 ret = proc_dointvec(table, write, file, buffer, lenp, ppos); 3026 ret = proc_dointvec(table, write, buffer, lenp, ppos);
3114 3027
3115 if (ret || !write || (last_ftrace_enabled == !!ftrace_enabled)) 3028 if (ret || !write || (last_ftrace_enabled == !!ftrace_enabled))
3116 goto out; 3029 goto out;