]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
misc: tegra-profiler: support special mappings
authorIgor Nabirushkin <inabirushkin@nvidia.com>
Thu, 13 Mar 2014 09:09:17 +0000 (13:09 +0400)
committerMrutyunjay Sawant <msawant@nvidia.com>
Mon, 14 Apr 2014 13:42:52 +0000 (06:42 -0700)
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/387505
Reviewed-by: Automatic_Commit_Validation_User
Tested-by: Maxim Morin <mmorin@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
drivers/misc/tegra-profiler/comm.c
drivers/misc/tegra-profiler/main.c
drivers/misc/tegra-profiler/mmap.c
drivers/misc/tegra-profiler/quadd_proc.c
drivers/misc/tegra-profiler/version.h
include/linux/tegra_profiler.h

index b0be0d2d34a0795b819854a2239afe9528decdaa..b81b99677554202b62ade853f212172695c828ae 100644 (file)
@@ -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;
index 65184ea33b84cd634e7ca43fa2b146fb93f5ffb2..f2ada7437e548bfd4d10cfd896cb6cbe2a816f27 100644 (file)
@@ -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;
 }
index 9e7c776a6b9ea0ec772311024ebbf61a7606cca0..0511c48111ba21a08692a2038252ff82caabb03f 100644 (file)
 
 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;
index 2fb37ae9dc8492cceb14d50b40b6ee60350510e1..9f9eee91eee842c64ab26d7273f1521cc071f7dc 100644 (file)
@@ -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");
index c0da0dabeb35de4e4cb8e6aaa0590d14ee8362dc..ad3dd972e53c430d89ea356d588c81e884bd6c4e 100644 (file)
@@ -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 */
index d56cf0f288eb0189bda24cec1e3768ce6d91fada..ef5b7f1494c3fd9e3ac0b1bb345b7363e3d2aec5 100644 (file)
@@ -19,7 +19,7 @@
 
 #include <linux/ioctl.h>
 
-#define QUADD_SAMPLES_VERSION  23
+#define QUADD_SAMPLES_VERSION  24
 #define QUADD_IO_VERSION       10
 
 #define QUADD_IO_VERSION_DYNAMIC_RB            5
@@ -34,6 +34,7 @@
 #define QUADD_SAMPLE_VERSION_THREAD_STATE_FLD  19
 #define QUADD_SAMPLE_VERSION_BT_UNWIND_TABLES  22
 #define QUADD_SAMPLE_VERSION_SUPPORT_IP64      23
+#define QUADD_SAMPLE_VERSION_SPECIAL_MMAP      24
 
 #define QUADD_MAX_COUNTERS     32
 #define QUADD_MAX_PROCESS      64
@@ -180,6 +181,8 @@ struct quadd_sample_data {
        u32 events_flags;
 };
 
+#define QUADD_MMAP_ED_IS_FILE_EXISTS   (1 << 0)
+
 struct quadd_mmap_data {
        u32 pid;
 
@@ -340,6 +343,8 @@ enum {
 #define QUADD_COMM_CAP_EXTRA_GET_MMAP          (1 << 1)
 #define QUADD_COMM_CAP_EXTRA_GROUP_SAMPLES     (1 << 2)
 #define QUADD_COMM_CAP_EXTRA_BT_UNWIND_TABLES  (1 << 3)
+#define QUADD_COMM_CAP_EXTRA_SUPPORT_AARCH64   (1 << 4)
+#define QUADD_COMM_CAP_EXTRA_SPECIAL_ARCH_MMAP (1 << 5)
 
 struct quadd_comm_cap {
        u32     pmu:1,