summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorIgor Nabirushkin <inabirushkin@nvidia.com>2014-03-13 13:09:17 +0400
committerGabby Lee <galee@nvidia.com>2014-04-24 18:15:38 -0700
commit1dd6fa692bed0e1902213808581187ad9ea86c33 (patch)
treedb982767546d2b074455088922df3adae0dfc01f /drivers
parent2c2b7e2d82825f04b07f437aa75eb2c35d9bb654 (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.c2
-rw-r--r--drivers/misc/tegra-profiler/main.c3
-rw-r--r--drivers/misc/tegra-profiler/mmap.c143
-rw-r--r--drivers/misc/tegra-profiler/quadd_proc.c22
-rw-r--r--drivers/misc/tegra-profiler/version.h2
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 */