diff options
| -rw-r--r-- | kernel/trace/ftrace.c | 61 |
1 files changed, 24 insertions, 37 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 53ed01ed7aa7..e10f9e522c44 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
| @@ -1520,35 +1520,6 @@ static void ftrace_hash_rec_enable(struct ftrace_ops *ops, | |||
| 1520 | __ftrace_hash_rec_update(ops, filter_hash, 1); | 1520 | __ftrace_hash_rec_update(ops, filter_hash, 1); |
| 1521 | } | 1521 | } |
| 1522 | 1522 | ||
| 1523 | static struct dyn_ftrace *ftrace_alloc_dyn_node(unsigned long ip) | ||
| 1524 | { | ||
| 1525 | if (ftrace_pages->index == ftrace_pages->size) { | ||
| 1526 | /* We should have allocated enough */ | ||
| 1527 | if (WARN_ON(!ftrace_pages->next)) | ||
| 1528 | return NULL; | ||
| 1529 | ftrace_pages = ftrace_pages->next; | ||
| 1530 | } | ||
| 1531 | |||
| 1532 | return &ftrace_pages->records[ftrace_pages->index++]; | ||
| 1533 | } | ||
| 1534 | |||
| 1535 | static struct dyn_ftrace * | ||
| 1536 | ftrace_record_ip(unsigned long ip) | ||
| 1537 | { | ||
| 1538 | struct dyn_ftrace *rec; | ||
| 1539 | |||
| 1540 | if (ftrace_disabled) | ||
| 1541 | return NULL; | ||
| 1542 | |||
| 1543 | rec = ftrace_alloc_dyn_node(ip); | ||
| 1544 | if (!rec) | ||
| 1545 | return NULL; | ||
| 1546 | |||
| 1547 | rec->ip = ip; | ||
| 1548 | |||
| 1549 | return rec; | ||
| 1550 | } | ||
| 1551 | |||
| 1552 | static void print_ip_ins(const char *fmt, unsigned char *p) | 1523 | static void print_ip_ins(const char *fmt, unsigned char *p) |
| 1553 | { | 1524 | { |
| 1554 | int i; | 1525 | int i; |
| @@ -3693,7 +3664,9 @@ static int ftrace_process_locs(struct module *mod, | |||
| 3693 | unsigned long *start, | 3664 | unsigned long *start, |
| 3694 | unsigned long *end) | 3665 | unsigned long *end) |
| 3695 | { | 3666 | { |
| 3667 | struct ftrace_page *start_pg; | ||
| 3696 | struct ftrace_page *pg; | 3668 | struct ftrace_page *pg; |
| 3669 | struct dyn_ftrace *rec; | ||
| 3697 | unsigned long count; | 3670 | unsigned long count; |
| 3698 | unsigned long *p; | 3671 | unsigned long *p; |
| 3699 | unsigned long addr; | 3672 | unsigned long addr; |
| @@ -3708,8 +3681,8 @@ static int ftrace_process_locs(struct module *mod, | |||
| 3708 | sort(start, count, sizeof(*start), | 3681 | sort(start, count, sizeof(*start), |
| 3709 | ftrace_cmp_ips, ftrace_swap_ips); | 3682 | ftrace_cmp_ips, ftrace_swap_ips); |
| 3710 | 3683 | ||
| 3711 | pg = ftrace_allocate_pages(count); | 3684 | start_pg = ftrace_allocate_pages(count); |
| 3712 | if (!pg) | 3685 | if (!start_pg) |
| 3713 | return -ENOMEM; | 3686 | return -ENOMEM; |
| 3714 | 3687 | ||
| 3715 | mutex_lock(&ftrace_lock); | 3688 | mutex_lock(&ftrace_lock); |
| @@ -3722,7 +3695,7 @@ static int ftrace_process_locs(struct module *mod, | |||
| 3722 | if (!mod) { | 3695 | if (!mod) { |
| 3723 | WARN_ON(ftrace_pages || ftrace_pages_start); | 3696 | WARN_ON(ftrace_pages || ftrace_pages_start); |
| 3724 | /* First initialization */ | 3697 | /* First initialization */ |
| 3725 | ftrace_pages = ftrace_pages_start = pg; | 3698 | ftrace_pages = ftrace_pages_start = start_pg; |
| 3726 | } else { | 3699 | } else { |
| 3727 | if (!ftrace_pages) | 3700 | if (!ftrace_pages) |
| 3728 | goto out; | 3701 | goto out; |
| @@ -3733,11 +3706,11 @@ static int ftrace_process_locs(struct module *mod, | |||
| 3733 | ftrace_pages = ftrace_pages->next; | 3706 | ftrace_pages = ftrace_pages->next; |
| 3734 | } | 3707 | } |
| 3735 | 3708 | ||
| 3736 | ftrace_pages->next = pg; | 3709 | ftrace_pages->next = start_pg; |
| 3737 | ftrace_pages = pg; | ||
| 3738 | } | 3710 | } |
| 3739 | 3711 | ||
| 3740 | p = start; | 3712 | p = start; |
| 3713 | pg = start_pg; | ||
| 3741 | while (p < end) { | 3714 | while (p < end) { |
| 3742 | addr = ftrace_call_adjust(*p++); | 3715 | addr = ftrace_call_adjust(*p++); |
| 3743 | /* | 3716 | /* |
| @@ -3748,12 +3721,26 @@ static int ftrace_process_locs(struct module *mod, | |||
| 3748 | */ | 3721 | */ |
| 3749 | if (!addr) | 3722 | if (!addr) |
| 3750 | continue; | 3723 | continue; |
| 3751 | if (!ftrace_record_ip(addr)) | 3724 | |
| 3752 | break; | 3725 | if (pg->index == pg->size) { |
| 3726 | /* We should have allocated enough */ | ||
| 3727 | if (WARN_ON(!pg->next)) | ||
| 3728 | break; | ||
| 3729 | pg = pg->next; | ||
| 3730 | } | ||
| 3731 | |||
| 3732 | rec = &pg->records[pg->index++]; | ||
| 3733 | rec->ip = addr; | ||
| 3753 | } | 3734 | } |
| 3754 | 3735 | ||
| 3736 | /* We should have used all pages */ | ||
| 3737 | WARN_ON(pg->next); | ||
| 3738 | |||
| 3739 | /* Assign the last page to ftrace_pages */ | ||
| 3740 | ftrace_pages = pg; | ||
| 3741 | |||
| 3755 | /* These new locations need to be initialized */ | 3742 | /* These new locations need to be initialized */ |
| 3756 | ftrace_new_pgs = pg; | 3743 | ftrace_new_pgs = start_pg; |
| 3757 | 3744 | ||
| 3758 | /* | 3745 | /* |
| 3759 | * We only need to disable interrupts on start up | 3746 | * We only need to disable interrupts on start up |
