diff options
Diffstat (limited to 'kernel/trace/ftrace.c')
| -rw-r--r-- | kernel/trace/ftrace.c | 233 |
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 | ||
| 1324 | enum { | 1323 | enum { |
| 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 | ||
| 1344 | static void * | 1341 | static 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 | ||
| 1525 | static struct seq_operations show_ftrace_seq_ops = { | 1522 | static 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, ¬); | 2071 | type = ftrace_setup_glob(glob, strlen(glob), &search, ¬); |
| @@ -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); | ||
| 2233 | out: | ||
| 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; | |||
| 2457 | static void * | 2415 | static 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 | ||
| 2467 | static void * | 2423 | static 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 | ||
| 2507 | static struct seq_operations ftrace_graph_seq_ops = { | 2463 | static 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 | |||
| 2602 | ftrace_graph_write(struct file *file, const char __user *ubuf, | 2552 | ftrace_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 | |
| 2587 | out_free: | ||
| 2588 | trace_parser_put(&parser); | ||
| 2589 | out_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 |
| 2743 | void ftrace_release(void *start, void *end) | 2660 | void 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 | ||
| 3101 | int | 3014 | int |
| 3102 | ftrace_enable_sysctl(struct ctl_table *table, int write, | 3015 | ftrace_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; |
