diff options
-rw-r--r-- | kernel/trace/ftrace.c | 43 |
1 files changed, 28 insertions, 15 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 37f9e90d241c..92376aeac4a7 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
@@ -1507,25 +1507,38 @@ static bool test_rec_ops_needs_regs(struct dyn_ftrace *rec) | |||
1507 | static void ftrace_remove_tramp(struct ftrace_ops *ops, | 1507 | static void ftrace_remove_tramp(struct ftrace_ops *ops, |
1508 | struct dyn_ftrace *rec) | 1508 | struct dyn_ftrace *rec) |
1509 | { | 1509 | { |
1510 | struct ftrace_func_entry *entry; | 1510 | /* If TRAMP is not set, no ops should have a trampoline for this */ |
1511 | 1511 | if (!(rec->flags & FTRACE_FL_TRAMP)) | |
1512 | entry = ftrace_lookup_ip(ops->tramp_hash, rec->ip); | ||
1513 | if (!entry) | ||
1514 | return; | 1512 | return; |
1515 | 1513 | ||
1514 | rec->flags &= ~FTRACE_FL_TRAMP; | ||
1515 | |||
1516 | if ((!ftrace_hash_empty(ops->func_hash->filter_hash) && | ||
1517 | !ftrace_lookup_ip(ops->func_hash->filter_hash, rec->ip)) || | ||
1518 | ftrace_lookup_ip(ops->func_hash->notrace_hash, rec->ip)) | ||
1519 | return; | ||
1516 | /* | 1520 | /* |
1517 | * The tramp_hash entry will be removed at time | 1521 | * The tramp_hash entry will be removed at time |
1518 | * of update. | 1522 | * of update. |
1519 | */ | 1523 | */ |
1520 | ops->nr_trampolines--; | 1524 | ops->nr_trampolines--; |
1521 | rec->flags &= ~FTRACE_FL_TRAMP; | ||
1522 | } | 1525 | } |
1523 | 1526 | ||
1524 | static void ftrace_clear_tramps(struct dyn_ftrace *rec) | 1527 | static void ftrace_clear_tramps(struct dyn_ftrace *rec, struct ftrace_ops *ops) |
1525 | { | 1528 | { |
1526 | struct ftrace_ops *op; | 1529 | struct ftrace_ops *op; |
1527 | 1530 | ||
1531 | /* If TRAMP is not set, no ops should have a trampoline for this */ | ||
1532 | if (!(rec->flags & FTRACE_FL_TRAMP)) | ||
1533 | return; | ||
1534 | |||
1528 | do_for_each_ftrace_op(op, ftrace_ops_list) { | 1535 | do_for_each_ftrace_op(op, ftrace_ops_list) { |
1536 | /* | ||
1537 | * This function is called to clear other tramps | ||
1538 | * not the one that is being updated. | ||
1539 | */ | ||
1540 | if (op == ops) | ||
1541 | continue; | ||
1529 | if (op->nr_trampolines) | 1542 | if (op->nr_trampolines) |
1530 | ftrace_remove_tramp(op, rec); | 1543 | ftrace_remove_tramp(op, rec); |
1531 | } while_for_each_ftrace_op(op); | 1544 | } while_for_each_ftrace_op(op); |
@@ -1626,13 +1639,10 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops, | |||
1626 | /* | 1639 | /* |
1627 | * If we are adding another function callback | 1640 | * If we are adding another function callback |
1628 | * to this function, and the previous had a | 1641 | * to this function, and the previous had a |
1629 | * trampoline used, then we need to go back to | 1642 | * custom trampoline in use, then we need to go |
1630 | * the default trampoline. | 1643 | * back to the default trampoline. |
1631 | */ | 1644 | */ |
1632 | rec->flags &= ~FTRACE_FL_TRAMP; | 1645 | ftrace_clear_tramps(rec, ops); |
1633 | |||
1634 | /* remove trampolines from any ops for this rec */ | ||
1635 | ftrace_clear_tramps(rec); | ||
1636 | } | 1646 | } |
1637 | 1647 | ||
1638 | /* | 1648 | /* |
@@ -1935,8 +1945,8 @@ unsigned long ftrace_get_addr_new(struct dyn_ftrace *rec) | |||
1935 | if (rec->flags & FTRACE_FL_TRAMP) { | 1945 | if (rec->flags & FTRACE_FL_TRAMP) { |
1936 | ops = ftrace_find_tramp_ops_new(rec); | 1946 | ops = ftrace_find_tramp_ops_new(rec); |
1937 | if (FTRACE_WARN_ON(!ops || !ops->trampoline)) { | 1947 | if (FTRACE_WARN_ON(!ops || !ops->trampoline)) { |
1938 | pr_warning("Bad trampoline accounting at: %p (%pS)\n", | 1948 | pr_warn("Bad trampoline accounting at: %p (%pS) (%lx)\n", |
1939 | (void *)rec->ip, (void *)rec->ip); | 1949 | (void *)rec->ip, (void *)rec->ip, rec->flags); |
1940 | /* Ftrace is shutting down, return anything */ | 1950 | /* Ftrace is shutting down, return anything */ |
1941 | return (unsigned long)FTRACE_ADDR; | 1951 | return (unsigned long)FTRACE_ADDR; |
1942 | } | 1952 | } |
@@ -2266,7 +2276,10 @@ static int ftrace_save_ops_tramp_hash(struct ftrace_ops *ops) | |||
2266 | } while_for_each_ftrace_rec(); | 2276 | } while_for_each_ftrace_rec(); |
2267 | 2277 | ||
2268 | /* The number of recs in the hash must match nr_trampolines */ | 2278 | /* The number of recs in the hash must match nr_trampolines */ |
2269 | FTRACE_WARN_ON(ops->tramp_hash->count != ops->nr_trampolines); | 2279 | if (FTRACE_WARN_ON(ops->tramp_hash->count != ops->nr_trampolines)) |
2280 | pr_warn("count=%ld trampolines=%d\n", | ||
2281 | ops->tramp_hash->count, | ||
2282 | ops->nr_trampolines); | ||
2270 | 2283 | ||
2271 | return 0; | 2284 | return 0; |
2272 | } | 2285 | } |