diff options
author | Igor Nabirushkin <inabirushkin@nvidia.com> | 2014-03-13 13:09:17 +0400 |
---|---|---|
committer | Gabby Lee <galee@nvidia.com> | 2014-04-24 18:15:38 -0700 |
commit | 1dd6fa692bed0e1902213808581187ad9ea86c33 (patch) | |
tree | db982767546d2b074455088922df3adae0dfc01f /drivers | |
parent | 2c2b7e2d82825f04b07f437aa75eb2c35d9bb654 (diff) |
misc: tegra-profiler: support special mappings
Tegra Profiler: support special architecture mappings
Bug 1480667
Change-Id: I2f1bd67d99888d39bc713a5c58d295b121ad18b2
Signed-off-by: Igor Nabirushkin <inabirushkin@nvidia.com>
Reviewed-on: http://git-master/r/381407
(cherry picked from commit 75aeabcf32fb9967f74d046445a830cc606da59d)
Reviewed-on: http://git-master/r/398137
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Tested-by: Maxim Morin <mmorin@nvidia.com>
Reviewed-by: Gabby Lee <galee@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/misc/tegra-profiler/comm.c | 2 | ||||
-rw-r--r-- | drivers/misc/tegra-profiler/main.c | 3 | ||||
-rw-r--r-- | drivers/misc/tegra-profiler/mmap.c | 143 | ||||
-rw-r--r-- | drivers/misc/tegra-profiler/quadd_proc.c | 22 | ||||
-rw-r--r-- | drivers/misc/tegra-profiler/version.h | 2 |
5 files changed, 126 insertions, 46 deletions
diff --git a/drivers/misc/tegra-profiler/comm.c b/drivers/misc/tegra-profiler/comm.c index b0be0d2d34a0..b81b99677554 100644 --- a/drivers/misc/tegra-profiler/comm.c +++ b/drivers/misc/tegra-profiler/comm.c @@ -302,7 +302,7 @@ static ssize_t read_sample(char __user *buffer, size_t max_length) break; case QUADD_RECORD_TYPE_MMAP: - length_extra = sizeof(u64); + length_extra = sizeof(u64) * 2; if (record.mmap.filename_length > 0) { length_extra += record.mmap.filename_length; diff --git a/drivers/misc/tegra-profiler/main.c b/drivers/misc/tegra-profiler/main.c index 65184ea33b84..f2ada7437e54 100644 --- a/drivers/misc/tegra-profiler/main.c +++ b/drivers/misc/tegra-profiler/main.c @@ -412,6 +412,9 @@ static void get_capabilities(struct quadd_comm_cap *cap) extra |= QUADD_COMM_CAP_EXTRA_BT_KERNEL_CTX; extra |= QUADD_COMM_CAP_EXTRA_GET_MMAP; extra |= QUADD_COMM_CAP_EXTRA_GROUP_SAMPLES; + extra |= QUADD_COMM_CAP_EXTRA_BT_UNWIND_TABLES; + extra |= QUADD_COMM_CAP_EXTRA_SUPPORT_AARCH64; + extra |= QUADD_COMM_CAP_EXTRA_SPECIAL_ARCH_MMAP; cap->reserved[QUADD_COMM_CAP_IDX_EXTRA] = extra; } diff --git a/drivers/misc/tegra-profiler/mmap.c b/drivers/misc/tegra-profiler/mmap.c index 9e7c776a6b9e..0511c48111ba 100644 --- a/drivers/misc/tegra-profiler/mmap.c +++ b/drivers/misc/tegra-profiler/mmap.c @@ -30,34 +30,43 @@ static void put_mmap_sample(struct quadd_mmap_data *s, char *filename, - size_t length, unsigned long pgoff) + size_t length, unsigned long pgoff, int is_file_exists) { + u64 mmap_ed = 0; struct quadd_record_data r; - struct quadd_iovec vec[2]; - u64 pgoff_val = pgoff << PAGE_SHIFT; + struct quadd_iovec vec[3]; + u64 pgoff_val = (u64)pgoff << PAGE_SHIFT; r.record_type = QUADD_RECORD_TYPE_MMAP; memcpy(&r.mmap, s, sizeof(*s)); r.mmap.filename_length = length; + if (is_file_exists) + mmap_ed |= QUADD_MMAP_ED_IS_FILE_EXISTS; + vec[0].base = &pgoff_val; vec[0].len = sizeof(pgoff_val); - vec[1].base = filename; - vec[1].len = length; + vec[1].base = &mmap_ed; + vec[1].len = sizeof(mmap_ed); + + vec[2].base = filename; + vec[2].len = length; - pr_debug("MMAP: pid: %u, file_name: '%s', addr: %#llx - %#llx, len: %llx, pgoff: %#lx\n", - s->pid, filename, s->addr, s->addr + s->len, s->len, pgoff); + pr_debug("MMAP: pid: %u, file_name: '%s', addr: %#llx - %#llx, len: %llx, pgoff: %#llx\n", + s->pid, filename, + s->addr, s->addr + s->len, s->len, pgoff_val); quadd_put_sample(&r, vec, ARRAY_SIZE(vec)); } void quadd_process_mmap(struct vm_area_struct *vma, pid_t pid) { + int is_file_exists; struct file *vm_file; struct path *path; - char *file_name, *tmp_buf; + char *file_name, *tmp_buf = NULL; struct quadd_mmap_data sample; size_t length, length_aligned; @@ -67,22 +76,55 @@ void quadd_process_mmap(struct vm_area_struct *vma, pid_t pid) if (!(vma->vm_flags & VM_EXEC)) return; - vm_file = vma->vm_file; - if (!vm_file) - return; - - path = &vm_file->f_path; - tmp_buf = kzalloc(PATH_MAX + sizeof(u64), GFP_KERNEL); if (!tmp_buf) return; - file_name = d_path(path, tmp_buf, PATH_MAX); - if (IS_ERR(file_name)) - goto out; + vm_file = vma->vm_file; + if (vm_file) { + path = &vm_file->f_path; + + file_name = d_path(path, tmp_buf, PATH_MAX); + if (IS_ERR(file_name)) + goto out; + + if (strstr(file_name, " (deleted)")) + goto out; + + length = strlen(file_name) + 1; + + is_file_exists = 1; + } else { + const char *name = NULL; + + name = arch_vma_name(vma); + if (!name) { + struct mm_struct *mm = vma->vm_mm; + + if (!mm) { + name = "[vdso]"; + } else if (vma->vm_start <= mm->start_brk && + vma->vm_end >= mm->brk) { + name = "[heap]"; + } else if (vma->vm_start <= mm->start_stack && + vma->vm_end >= mm->start_stack) { + name = "[stack]"; + } + } + + if (name) + strcpy(tmp_buf, name); + else + sprintf(tmp_buf, "[vma:%08lx-%08lx]", + vma->vm_start, vma->vm_end); + + file_name = tmp_buf; + length = strlen(file_name) + 1; + + is_file_exists = 0; + } - if (strstr(file_name, " (deleted)")) - goto out; + length_aligned = ALIGN(length, sizeof(u64)); sample.pid = pid; sample.user_mode = 1; @@ -90,10 +132,8 @@ void quadd_process_mmap(struct vm_area_struct *vma, pid_t pid) sample.addr = vma->vm_start; sample.len = vma->vm_end - vma->vm_start; - length = strlen(file_name) + 1; - length_aligned = ALIGN(length, sizeof(u64)); - - put_mmap_sample(&sample, file_name, length_aligned, vma->vm_pgoff); + put_mmap_sample(&sample, file_name, length_aligned, + vma->vm_pgoff, is_file_exists); out: kfree(tmp_buf); @@ -101,6 +141,7 @@ out: int quadd_get_current_mmap(pid_t pid) { + int is_file_exists; struct vm_area_struct *vma; struct file *vm_file; struct path *path; @@ -136,19 +177,48 @@ int quadd_get_current_mmap(pid_t pid) continue; vm_file = vma->vm_file; - if (!vm_file) - continue; - - path = &vm_file->f_path; + if (vm_file) { + path = &vm_file->f_path; + + file_name = d_path(path, tmp_buf, PATH_MAX); + if (IS_ERR(file_name)) + continue; + + if (strstr(file_name, " (deleted)")) + continue; + + length = strlen(file_name) + 1; + is_file_exists = 1; + } else { + const char *name = NULL; + + name = arch_vma_name(vma); + if (!name) { + mm = vma->vm_mm; + + if (!mm) { + name = "[vdso]"; + } else if (vma->vm_start <= mm->start_brk && + vma->vm_end >= mm->brk) { + name = "[heap]"; + } else if (vma->vm_start <= mm->start_stack && + vma->vm_end >= mm->start_stack) { + name = "[stack]"; + } + } + + if (name) + strcpy(tmp_buf, name); + else + sprintf(tmp_buf, "[vma:%08lx-%08lx]", + vma->vm_start, vma->vm_end); + + file_name = tmp_buf; + length = strlen(file_name) + 1; + + is_file_exists = 0; + } - file_name = d_path(path, tmp_buf, PATH_MAX); - if (IS_ERR(file_name)) - continue; - - if (strstr(file_name, " (deleted)")) - continue; - - length = strlen(file_name) + 1; length_aligned = ALIGN(length, sizeof(u64)); sample.pid = pid; @@ -158,8 +228,9 @@ int quadd_get_current_mmap(pid_t pid) sample.len = vma->vm_end - vma->vm_start; put_mmap_sample(&sample, file_name, length_aligned, - vma->vm_pgoff); + vma->vm_pgoff, is_file_exists); } + kfree(tmp_buf); return 0; diff --git a/drivers/misc/tegra-profiler/quadd_proc.c b/drivers/misc/tegra-profiler/quadd_proc.c index 2fb37ae9dc84..9f9eee91eee8 100644 --- a/drivers/misc/tegra-profiler/quadd_proc.c +++ b/drivers/misc/tegra-profiler/quadd_proc.c @@ -59,28 +59,34 @@ static int show_capabilities(struct seq_file *f, void *offset) struct quadd_events_cap *event = &cap->events_cap; unsigned int extra = cap->reserved[QUADD_COMM_CAP_IDX_EXTRA]; - seq_printf(f, "pmu: %s\n", + seq_printf(f, "pmu: %s\n", YES_NO(cap->pmu)); - seq_printf(f, "tegra 3 LP cluster: %s\n", + seq_printf(f, "tegra 3 LP cluster: %s\n", YES_NO(cap->tegra_lp_cluster)); - seq_printf(f, "power rate samples: %s\n", + seq_printf(f, "power rate samples: %s\n", YES_NO(cap->power_rate)); - seq_printf(f, "l2 cache: %s\n", + seq_printf(f, "l2 cache: %s\n", YES_NO(cap->l2_cache)); if (cap->l2_cache) { seq_printf(f, "multiple l2 events: %s\n", YES_NO(cap->l2_multiple_events)); } - seq_printf(f, "support polling mode: %s\n", + seq_printf(f, "support polling mode: %s\n", YES_NO(cap->blocked_read)); - seq_printf(f, "backtrace from the kernel ctx: %s\n", + seq_printf(f, "backtrace from the kernel ctx: %s\n", YES_NO(extra & QUADD_COMM_CAP_EXTRA_BT_KERNEL_CTX)); - seq_printf(f, "send mmap regions at the start: %s\n", + seq_printf(f, "send mmap regions at the start: %s\n", YES_NO(extra & QUADD_COMM_CAP_EXTRA_GET_MMAP)); - seq_printf(f, "group samples: %s\n", + seq_printf(f, "group samples: %s\n", YES_NO(extra & QUADD_COMM_CAP_EXTRA_GROUP_SAMPLES)); + seq_printf(f, "unwinding based on ex-handling tables: %s\n", + YES_NO(extra & QUADD_COMM_CAP_EXTRA_BT_UNWIND_TABLES)); + seq_printf(f, "support AArch64 architecture: %s\n", + YES_NO(extra & QUADD_COMM_CAP_EXTRA_SUPPORT_AARCH64)); + seq_printf(f, "support special architecture mappings: %s\n", + YES_NO(extra & QUADD_COMM_CAP_EXTRA_SPECIAL_ARCH_MMAP)); seq_puts(f, "\n"); seq_puts(f, "Supported events:\n"); diff --git a/drivers/misc/tegra-profiler/version.h b/drivers/misc/tegra-profiler/version.h index c0da0dabeb35..ad3dd972e53c 100644 --- a/drivers/misc/tegra-profiler/version.h +++ b/drivers/misc/tegra-profiler/version.h @@ -18,7 +18,7 @@ #ifndef __QUADD_VERSION_H #define __QUADD_VERSION_H -#define QUADD_MODULE_VERSION "1.59" +#define QUADD_MODULE_VERSION "1.60" #define QUADD_MODULE_BRANCH "Dev" #endif /* __QUADD_VERSION_H */ |