diff options
| author | Igor Nabirushkin <inabirushkin@nvidia.com> | 2018-11-08 05:49:42 -0500 |
|---|---|---|
| committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2019-01-18 02:51:12 -0500 |
| commit | a6614067673a5e61444fcfcb6c9826bdcf60c28e (patch) | |
| tree | 2e6a50c2732a2e75a2abfa7639d594671c32a07d | |
| parent | 7361e6a275affd6eb5231d6c4b5dae79ad514438 (diff) | |
tegra-profiler: dwarf: support multiple processes
- Support DWARF/ARM-EHABI unwinding for multiple processes.
- Add cpu_id for MMAP samples.
Bug 2438564
Jira DTSP-824
Jira DTSP-1599
Change-Id: I998906011cff240b9a554cd40679cd9ec9c0f7b7
Signed-off-by: Igor Nabirushkin <inabirushkin@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1945653
(cherry picked from commit 20e2cf7d2509dfc4708f4a3720aee26852998f13)
Reviewed-on: https://git-master.nvidia.com/r/1992080
Reviewed-by: Dmitry Antipov <dantipov@nvidia.com>
Reviewed-by: Bibek Basu <bbasu@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
| -rw-r--r-- | drivers/misc/tegra-profiler/comm.c | 127 | ||||
| -rw-r--r-- | drivers/misc/tegra-profiler/comm.h | 3 | ||||
| -rw-r--r-- | drivers/misc/tegra-profiler/dwarf_unwind.c | 136 | ||||
| -rw-r--r-- | drivers/misc/tegra-profiler/eh_unwind.c | 732 | ||||
| -rw-r--r-- | drivers/misc/tegra-profiler/eh_unwind.h | 66 | ||||
| -rw-r--r-- | drivers/misc/tegra-profiler/hrt.c | 8 | ||||
| -rw-r--r-- | drivers/misc/tegra-profiler/main.c | 4 | ||||
| -rw-r--r-- | drivers/misc/tegra-profiler/mmap.c | 48 | ||||
| -rw-r--r-- | drivers/misc/tegra-profiler/quadd.h | 6 | ||||
| -rw-r--r-- | drivers/misc/tegra-profiler/version.h | 2 | ||||
| -rw-r--r-- | include/linux/tegra_profiler.h | 64 |
11 files changed, 715 insertions, 481 deletions
diff --git a/drivers/misc/tegra-profiler/comm.c b/drivers/misc/tegra-profiler/comm.c index df632a272..9625851a3 100644 --- a/drivers/misc/tegra-profiler/comm.c +++ b/drivers/misc/tegra-profiler/comm.c | |||
| @@ -58,9 +58,6 @@ struct quadd_comm_ctx { | |||
| 58 | int params_ok; | 58 | int params_ok; |
| 59 | 59 | ||
| 60 | struct miscdevice *misc_dev; | 60 | struct miscdevice *misc_dev; |
| 61 | |||
| 62 | struct list_head mmap_areas; | ||
| 63 | raw_spinlock_t mmaps_lock; | ||
| 64 | }; | 61 | }; |
| 65 | 62 | ||
| 66 | struct comm_cpu_context { | 63 | struct comm_cpu_context { |
| @@ -230,12 +227,11 @@ static struct quadd_comm_data_interface comm_data = { | |||
| 230 | .is_active = is_active, | 227 | .is_active = is_active, |
| 231 | }; | 228 | }; |
| 232 | 229 | ||
| 233 | static struct quadd_mmap_area * | 230 | static struct quadd_mmap_area *find_mmap_by_vma(unsigned long vm_start) |
| 234 | find_mmap(unsigned long vm_start) | ||
| 235 | { | 231 | { |
| 236 | struct quadd_mmap_area *entry; | 232 | struct quadd_mmap_area *entry; |
| 237 | 233 | ||
| 238 | list_for_each_entry(entry, &comm_ctx.mmap_areas, list) { | 234 | list_for_each_entry(entry, &comm_ctx.ctx->mmap_areas, list) { |
| 239 | struct vm_area_struct *mmap_vma = entry->mmap_vma; | 235 | struct vm_area_struct *mmap_vma = entry->mmap_vma; |
| 240 | 236 | ||
| 241 | if (vm_start == mmap_vma->vm_start) | 237 | if (vm_start == mmap_vma->vm_start) |
| @@ -245,6 +241,18 @@ find_mmap(unsigned long vm_start) | |||
| 245 | return NULL; | 241 | return NULL; |
| 246 | } | 242 | } |
| 247 | 243 | ||
| 244 | static struct quadd_mmap_area *find_mmap_by_hash(unsigned int hash) | ||
| 245 | { | ||
| 246 | struct quadd_mmap_area *entry; | ||
| 247 | |||
| 248 | list_for_each_entry(entry, &comm_ctx.ctx->mmap_areas, list) { | ||
| 249 | if (hash == entry->fi.file_hash) | ||
| 250 | return entry; | ||
| 251 | } | ||
| 252 | |||
| 253 | return NULL; | ||
| 254 | } | ||
| 255 | |||
| 248 | static int device_open(struct inode *inode, struct file *file) | 256 | static int device_open(struct inode *inode, struct file *file) |
| 249 | { | 257 | { |
| 250 | int err; | 258 | int err; |
| @@ -432,7 +440,8 @@ device_ioctl(struct file *file, | |||
| 432 | unsigned long ioctl_param) | 440 | unsigned long ioctl_param) |
| 433 | { | 441 | { |
| 434 | int err = 0; | 442 | int err = 0; |
| 435 | unsigned int cpuid; | 443 | unsigned int cpuid, file_hash; |
| 444 | unsigned long mmap_start; | ||
| 436 | struct quadd_mmap_area *mmap; | 445 | struct quadd_mmap_area *mmap; |
| 437 | struct quadd_parameters *user_params; | 446 | struct quadd_parameters *user_params; |
| 438 | struct quadd_pmu_setup_for_cpu *cpu_pmu_params; | 447 | struct quadd_pmu_setup_for_cpu *cpu_pmu_params; |
| @@ -673,26 +682,43 @@ device_ioctl(struct file *file, | |||
| 673 | goto error_out; | 682 | goto error_out; |
| 674 | } | 683 | } |
| 675 | 684 | ||
| 676 | pr_debug("%s: user_mmap_start: %#llx, sections vma: %#llx - %#llx\n", | 685 | mmap_start = (unsigned long)extabs.user_mmap_start; |
| 677 | __func__, | 686 | file_hash = extabs.file_hash; |
| 678 | (unsigned long long)extabs.user_mmap_start, | ||
| 679 | (unsigned long long)extabs.vm_start, | ||
| 680 | (unsigned long long)extabs.vm_end); | ||
| 681 | 687 | ||
| 682 | raw_spin_lock(&comm_ctx.mmaps_lock); | 688 | pr_debug("%s: mmap_start: %#lx, hash: %#x, sec: %#lx - %#lx\n", |
| 683 | mmap = find_mmap(extabs.user_mmap_start); | 689 | __func__, mmap_start, file_hash, |
| 690 | (unsigned long)extabs.vm_start, | ||
| 691 | (unsigned long)extabs.vm_end); | ||
| 692 | |||
| 693 | raw_spin_lock(&comm_ctx.ctx->mmaps_lock); | ||
| 694 | |||
| 695 | mmap = mmap_start ? find_mmap_by_vma(mmap_start) : | ||
| 696 | find_mmap_by_hash(file_hash); | ||
| 684 | if (!mmap) { | 697 | if (!mmap) { |
| 685 | pr_err("%s: error: mmap is not found\n", __func__); | 698 | pr_err("%s: error: !mmap, start/hash: %#lx/%#x\n", |
| 699 | __func__, mmap_start, file_hash); | ||
| 686 | err = -ENXIO; | 700 | err = -ENXIO; |
| 687 | raw_spin_unlock(&comm_ctx.mmaps_lock); | 701 | raw_spin_unlock(&comm_ctx.ctx->mmaps_lock); |
| 702 | goto error_out; | ||
| 703 | } | ||
| 704 | |||
| 705 | if ((mmap_start && mmap->type != QUADD_MMAP_TYPE_NONE) || | ||
| 706 | (!mmap_start && mmap->type != QUADD_MMAP_TYPE_EXTABS)) { | ||
| 707 | pr_err("%s: wrong mmap: %d, start/hash: %#lx/%#x\n", | ||
| 708 | __func__, mmap->type, mmap_start, file_hash); | ||
| 709 | err = -ENXIO; | ||
| 710 | raw_spin_unlock(&comm_ctx.ctx->mmaps_lock); | ||
| 688 | goto error_out; | 711 | goto error_out; |
| 689 | } | 712 | } |
| 690 | 713 | ||
| 691 | mmap->type = QUADD_MMAP_TYPE_EXTABS; | 714 | mmap->type = QUADD_MMAP_TYPE_EXTABS; |
| 692 | mmap->rb = NULL; | 715 | mmap->rb = NULL; |
| 693 | 716 | ||
| 717 | if (mmap_start) | ||
| 718 | mmap->fi.file_hash = extabs.file_hash; | ||
| 719 | |||
| 694 | err = comm_ctx.control->set_extab(&extabs, mmap); | 720 | err = comm_ctx.control->set_extab(&extabs, mmap); |
| 695 | raw_spin_unlock(&comm_ctx.mmaps_lock); | 721 | raw_spin_unlock(&comm_ctx.ctx->mmaps_lock); |
| 696 | if (err) { | 722 | if (err) { |
| 697 | pr_err("error: set_sections_info\n"); | 723 | pr_err("error: set_sections_info\n"); |
| 698 | goto error_out; | 724 | goto error_out; |
| @@ -702,24 +728,35 @@ device_ioctl(struct file *file, | |||
| 702 | case IOCTL_SET_MMAP_RB: | 728 | case IOCTL_SET_MMAP_RB: |
| 703 | if (copy_from_user(&mmap_rb, (void __user *)ioctl_param, | 729 | if (copy_from_user(&mmap_rb, (void __user *)ioctl_param, |
| 704 | sizeof(mmap_rb))) { | 730 | sizeof(mmap_rb))) { |
| 705 | pr_err("%s: error: mmap_rb failed\n", __func__); | ||
| 706 | err = -EFAULT; | 731 | err = -EFAULT; |
| 707 | goto error_out; | 732 | goto error_out; |
| 708 | } | 733 | } |
| 709 | 734 | ||
| 710 | raw_spin_lock(&comm_ctx.mmaps_lock); | 735 | raw_spin_lock(&comm_ctx.ctx->mmaps_lock); |
| 711 | mmap = find_mmap((unsigned long)mmap_rb.vm_start); | 736 | |
| 712 | raw_spin_unlock(&comm_ctx.mmaps_lock); | 737 | mmap = find_mmap_by_vma((unsigned long)mmap_rb.vm_start); |
| 713 | if (!mmap) { | 738 | if (!mmap) { |
| 714 | pr_err("%s: error: mmap is not found\n", __func__); | 739 | pr_err("set_mmap_rb: mmap is not found, start: %#lx\n", |
| 740 | (unsigned long)mmap_rb.vm_start); | ||
| 741 | err = -ENXIO; | ||
| 742 | raw_spin_unlock(&comm_ctx.ctx->mmaps_lock); | ||
| 743 | goto error_out; | ||
| 744 | } | ||
| 745 | |||
| 746 | if (mmap->type != QUADD_MMAP_TYPE_NONE) { | ||
| 747 | pr_err("set_mmap_rb: wrong mmap: %d, start: %#lx\n", | ||
| 748 | mmap->type, mmap->mmap_vma->vm_start); | ||
| 715 | err = -ENXIO; | 749 | err = -ENXIO; |
| 750 | raw_spin_unlock(&comm_ctx.ctx->mmaps_lock); | ||
| 716 | goto error_out; | 751 | goto error_out; |
| 717 | } | 752 | } |
| 753 | |||
| 718 | mmap->type = QUADD_MMAP_TYPE_RB; | 754 | mmap->type = QUADD_MMAP_TYPE_RB; |
| 719 | 755 | ||
| 720 | err = init_mmap_hdr(&mmap_rb, mmap); | 756 | err = init_mmap_hdr(&mmap_rb, mmap); |
| 757 | raw_spin_unlock(&comm_ctx.ctx->mmaps_lock); | ||
| 721 | if (err) { | 758 | if (err) { |
| 722 | pr_err("%s: error: init_mmap_hdr\n", __func__); | 759 | pr_err("set_mmap_rb: error: init_mmap_hdr\n"); |
| 723 | goto error_out; | 760 | goto error_out; |
| 724 | } | 761 | } |
| 725 | 762 | ||
| @@ -742,7 +779,7 @@ remove_mmap_entry(struct quadd_mmap_area *mmap) | |||
| 742 | { | 779 | { |
