misc: tegra-profiler: use mmap calls
Igor Nabirushkin [Sun, 26 Jan 2014 23:13:33 +0000 (03:13 +0400)]
Tegra Profiler: add mmap calls

Bug 1447662

Change-Id: I96614ab3c320fd028cf861ea970b5199bdcae1c7
Signed-off-by: Igor Nabirushkin <inabirushkin@nvidia.com>
Reviewed-on: http://git-master/r/365889
Tested-by: Daniel Horowitz <dhorowitz@nvidia.com>
Reviewed-by: Gabby Lee <galee@nvidia.com>

drivers/misc/tegra-profiler/Makefile
drivers/misc/tegra-profiler/comm.c
drivers/misc/tegra-profiler/hrt.c
drivers/misc/tegra-profiler/main.c
drivers/misc/tegra-profiler/mmap.c
drivers/misc/tegra-profiler/mmap.h
drivers/misc/tegra-profiler/quadd.h
drivers/misc/tegra-profiler/version.h
include/linux/tegra_profiler.h
mm/mmap.c
mm/mprotect.c

index b206c8d..c5d81af 100644 (file)
@@ -10,7 +10,7 @@
 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 # more details.
 #
-# Copyright (c) 2013, NVIDIA CORPORATION.  All rights reserved.
+# Copyright (c) 2014, NVIDIA CORPORATION.  All rights reserved.
 #
 
 obj-$(CONFIG_TEGRA_PROFILER) += tegra-profiler.o
@@ -18,7 +18,6 @@ obj-$(CONFIG_TEGRA_PROFILER) += tegra-profiler.o
 tegra-profiler-objs := \
        main.o \
        armv7_pmu.o \
-       pl310.o \
        hrt.o \
        comm.o \
        mmap.o \
@@ -28,3 +27,7 @@ tegra-profiler-objs := \
        power_clk.o \
        auth.o \
        quadd_proc.o
+
+ifdef CONFIG_CACHE_L2X0
+tegra-profiler-objs += pl310.o
+endif
\ No newline at end of file
index c91af7c..ed2540c 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/poll.h>
 #include <linux/bitops.h>
 #include <linux/interrupt.h>
+#include <linux/err.h>
 
 #include <asm/uaccess.h>
 
@@ -712,8 +713,11 @@ static int comm_init(void)
 struct quadd_comm_data_interface *
 quadd_comm_events_init(struct quadd_comm_control_interface *control)
 {
-       if (comm_init() < 0)
-               return NULL;
+       int err;
+
+       err = comm_init();
+       if (err < 0)
+               return ERR_PTR(err);
 
        comm_ctx.control = control;
        return &comm_data;
index d1a67c6..638d08d 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/ratelimit.h>
 #include <linux/ptrace.h>
 #include <linux/interrupt.h>
+#include <linux/err.h>
 
 #include <asm/cputype.h>
 #include <asm/irq_regs.h>
@@ -56,7 +57,7 @@ static enum hrtimer_restart hrtimer_handler(struct hrtimer *hrtimer)
 
        regs = get_irq_regs();
 
-       if (hrt.active == 0)
+       if (!hrt.active)
                return HRTIMER_NORESTART;
 
        qm_debug_handler_sample(regs);
@@ -274,8 +275,6 @@ read_all_sources(struct pt_regs *regs, struct task_struct *task)
                        return;
        }
 
-       quadd_get_mmap_object(cpu_ctx, regs, task->pid);
-
        if (ctx->pmu && ctx->pmu_info.active)
                nr_events += read_source(ctx->pmu, regs,
                                         events, QUADD_MAX_COUNTERS);
@@ -339,12 +338,18 @@ read_all_sources(struct pt_regs *regs, struct task_struct *task)
        quadd_put_sample(&record_data, vec, vec_idx);
 }
 
-static inline int is_profile_process(pid_t pid)
+static inline int
+is_profile_process(struct task_struct *task)
 {
        int i;
-       pid_t profile_pid;
+       pid_t pid, profile_pid;
        struct quadd_ctx *ctx = hrt.quadd_ctx;
 
+       if (!task)
+               return 0;
+
+       pid = task->tgid;
+
        for (i = 0; i < ctx->param.nr_pids; i++) {
                profile_pid = ctx->param.pids[i];
                if (profile_pid == pid)
@@ -389,13 +394,12 @@ static int remove_active_thread(struct quadd_cpu_context *cpu_ctx, pid_t pid)
 void __quadd_task_sched_in(struct task_struct *prev,
                           struct task_struct *task)
 {
-       int current_flag;
        struct quadd_cpu_context *cpu_ctx = this_cpu_ptr(hrt.cpu_ctx);
        struct quadd_ctx *ctx = hrt.quadd_ctx;
        struct event_data events[QUADD_MAX_COUNTERS];
        /* static DEFINE_RATELIMIT_STATE(ratelimit_state, 5 * HZ, 2); */
 
-       if (likely(hrt.active == 0))
+       if (likely(!hrt.active))
                return;
 /*
        if (__ratelimit(&ratelimit_state))
@@ -404,9 +408,8 @@ void __quadd_task_sched_in(struct task_struct *prev,
                        (unsigned int)prev->tgid, (unsigned int)task->pid,
                        (unsigned int)task->tgid);
 */
-       current_flag = is_profile_process(task->tgid);
 
-       if (current_flag) {
+       if (is_profile_process(task)) {
                add_active_thread(cpu_ctx, task->pid, task->tgid);
                atomic_inc(&cpu_ctx->nr_active);
 
@@ -426,13 +429,13 @@ void __quadd_task_sched_in(struct task_struct *prev,
 void __quadd_task_sched_out(struct task_struct *prev,
                            struct task_struct *next)
 {
-       int n, prev_flag;
+       int n;
        struct pt_regs *user_regs;
        struct quadd_cpu_context *cpu_ctx = this_cpu_ptr(hrt.cpu_ctx);
        struct quadd_ctx *ctx = hrt.quadd_ctx;
        /* static DEFINE_RATELIMIT_STATE(ratelimit_state, 5 * HZ, 2); */
 
-       if (likely(hrt.active == 0))
+       if (likely(!hrt.active))
                return;
 /*
        if (__ratelimit(&ratelimit_state))
@@ -441,9 +444,8 @@ void __quadd_task_sched_out(struct task_struct *prev,
                        (unsigned int)prev->tgid, (unsigned int)next->pid,
                        (unsigned int)next->tgid);
 */
-       prev_flag = is_profile_process(prev->tgid);
 
-       if (prev_flag) {
+       if (is_profile_process(prev)) {
                user_regs = task_pt_regs(prev);
                if (user_regs)
                        read_all_sources(user_regs, prev);
@@ -461,6 +463,18 @@ void __quadd_task_sched_out(struct task_struct *prev,
        }
 }
 
+void __quadd_event_mmap(struct vm_area_struct *vma)
+{
+       if (likely(!hrt.active))
+               return;
+
+       if (!is_profile_process(current))
+               return;
+
+       quadd_process_mmap(vma);
+}
+EXPORT_SYMBOL(__quadd_event_mmap);
+
 static void reset_cpu_ctx(void)
 {
        int cpu_id;
@@ -485,7 +499,6 @@ int quadd_hrt_start(void)
        long freq;
        unsigned int extra;
        struct quadd_ctx *ctx = hrt.quadd_ctx;
-       struct quadd_cpu_context *cpu_ctx = this_cpu_ptr(hrt.cpu_ctx);
        struct quadd_parameters *param = &ctx->param;
 
        freq = ctx->param.freq;
@@ -507,7 +520,7 @@ int quadd_hrt_start(void)
        extra = param->reserved[QUADD_PARAM_IDX_EXTRA];
 
        if (extra & QUADD_PARAM_IDX_EXTRA_GET_MMAP) {
-               err = quadd_get_current_mmap(cpu_ctx, param->pids[0]);
+               err = quadd_get_current_mmap(param->pids[0]);
                if (err) {
                        pr_err("error: quadd_get_current_mmap\n");
                        return err;
@@ -582,7 +595,7 @@ struct quadd_hrt_ctx *quadd_hrt_init(struct quadd_ctx *ctx)
 
        hrt.cpu_ctx = alloc_percpu(struct quadd_cpu_context);
        if (!hrt.cpu_ctx)
-               return NULL;
+               return ERR_PTR(-ENOMEM);
 
        for (cpu_id = 0; cpu_id < nr_cpu_ids; cpu_id++) {
                cpu_ctx = per_cpu_ptr(hrt.cpu_ctx, cpu_id);
index ef69247..01544d0 100644 (file)
@@ -26,7 +26,6 @@
 #include "quadd.h"
 #include "armv7_pmu.h"
 #include "hrt.h"
-#include "pl310.h"
 #include "comm.h"
 #include "mmap.h"
 #include "debug.h"
 #include "version.h"
 #include "quadd_proc.h"
 
+#ifdef CONFIG_CACHE_L2X0
+#include "pl310.h"
+#endif
+
 static struct quadd_ctx ctx;
 
 static int get_default_properties(void)
@@ -92,7 +95,6 @@ static int start(void)
                        }
                }
 
-               quadd_mmap_reset();
                ctx.comm->reset();
 
                err = quadd_power_clk_start();
@@ -121,7 +123,6 @@ static void stop(void)
        if (atomic_cmpxchg(&ctx.started, 1, 0)) {
                quadd_hrt_stop();
 
-               quadd_mmap_reset();
                ctx.comm->reset();
 
                quadd_power_clk_stop();
@@ -457,7 +458,11 @@ static int __init quadd_module_init(void)
                                quadd_get_event_str(events[i]));
        }
 
+#ifdef CONFIG_CACHE_L2X0
        ctx.pl310 = quadd_l2x0_events_init();
+#else
+       ctx.pl310 = NULL;
+#endif
        if (ctx.pl310) {
                events = ctx.pl310_info.supported_events;
                nr_events = ctx.pl310->get_supported_events(events,
@@ -475,15 +480,9 @@ static int __init quadd_module_init(void)
        }
 
        ctx.hrt = quadd_hrt_init(&ctx);
-       if (!ctx.hrt) {
+       if (IS_ERR(ctx.hrt)) {
                pr_err("error: HRT init failed\n");
-               return -ENODEV;
-       }
-
-       ctx.mmap = quadd_mmap_init(&ctx);
-       if (IS_ERR(ctx.mmap)) {
-               pr_err("error: MMAP init failed\n");
-               return PTR_ERR(ctx.mmap);
+               return PTR_ERR(ctx.hrt);
        }
 
        err = quadd_power_clk_init(&ctx);
@@ -493,9 +492,9 @@ static int __init quadd_module_init(void)
        }
 
        ctx.comm = quadd_comm_events_init(&control);
-       if (!ctx.comm) {
+       if (IS_ERR(ctx.comm)) {
                pr_err("error: COMM init failed\n");
-               return -ENODEV;
+               return PTR_ERR(ctx.comm);
        }
 
        err = quadd_auth_init(&ctx);
@@ -515,7 +514,6 @@ static void __exit quadd_module_exit(void)
        pr_info("QuadD module exit\n");
 
        quadd_hrt_deinit();
-       quadd_mmap_deinit();
        quadd_power_clk_deinit();
        quadd_comm_events_exit();
        quadd_auth_deinit();
index bcec4b3..81abf36 100644 (file)
@@ -16,9 +16,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-#include <linux/module.h>
 #include <linux/mm.h>
-#include <linux/crc32.h>
 #include <linux/fs.h>
 #include <linux/slab.h>
 #include <linux/err.h>
 #include "mmap.h"
 #include "comm.h"
 #include "hrt.h"
-#include "debug.h"
-
-static struct quadd_mmap_ctx mmap_ctx;
-
-static int binary_search_and_add(unsigned int *array,
-                       unsigned int length, unsigned int key)
-{
-       unsigned int i_min, i_max, mid;
-
-       if (length == 0) {
-               array[0] = key;
-               return 1;
-       } else if (length == 1 && array[0] == key) {
-               return 0;
-       }
-
-       i_min = 0;
-       i_max = length;
-
-       if (array[0] > key) {
-               memmove((char *)((unsigned int *)array + 1), array,
-                       length * sizeof(unsigned int));
-               array[0] = key;
-               return 1;
-       } else if (array[length - 1] < key) {
-               array[length] = key;
-               return 1;
-       }
-
-       while (i_min < i_max) {
-               mid = i_min + (i_max - i_min) / 2;
-
-               if (key <= array[mid])
-                       i_max = mid;
-               else
-                       i_min = mid + 1;
-       }
-
-       if (array[i_max] == key) {
-               return 0;
-       } else {
-               memmove((char *)((unsigned int *)array + i_max + 1),
-                       (char *)((unsigned int *)array + i_max),
-                       (length - i_max) * sizeof(unsigned int));
-               array[i_max] = key;
-               return 1;
-       }
-}
-
-static int check_hash(u32 key)
-{
-       int res;
-       unsigned long flags;
-
-       spin_lock_irqsave(&mmap_ctx.lock, flags);
-
-       if (mmap_ctx.nr_hashes >= QUADD_MMAP_SIZE_ARRAY) {
-               spin_unlock_irqrestore(&mmap_ctx.lock, flags);
-               return 1;
-       }
-
-       res = binary_search_and_add(mmap_ctx.hash_array,
-                                   mmap_ctx.nr_hashes, key);
-       if (res > 0) {
-               mmap_ctx.nr_hashes++;
-               spin_unlock_irqrestore(&mmap_ctx.lock, flags);
-               return 0;
-       }
-
-       spin_unlock_irqrestore(&mmap_ctx.lock, flags);
-       return 1;
-}
-
-static int find_file(const char *file_name, unsigned long addr,
-                    unsigned long len)
-{
-       u32 crc;
-       size_t length;
-
-       if (!file_name)
-               return 0;
-
-       length = strlen(file_name);
-
-       crc = crc32_le(~0, file_name, length);
-       crc = crc32_le(crc, (unsigned char *)&addr,
-                      sizeof(addr));
-       crc = crc32_le(crc, (unsigned char *)&len,
-                      sizeof(len));
-
-       return check_hash(crc);
-}
 
 static void
 put_mmap_sample(struct quadd_mmap_data *s, char *filename,
@@ -138,89 +44,57 @@ put_mmap_sample(struct quadd_mmap_data *s, char *filename,
        vec.base = filename;
        vec.len = length;
 
-       pr_debug("MMAP: pid: %u, file_name: '%s', addr: %#llx, length: %llu",
-                s->pid, filename, s->addr, s->len);
+       pr_debug("MMAP: pid: %u, file_name: '%s', addr: %#llx - %#llx, len: %llx, pgoff: %#x\n",
+               s->pid, filename, s->addr, s->addr + s->len, s->len, s->pgoff);
 
        quadd_put_sample(&r, &vec, 1);
 }
 
-void quadd_get_mmap_object(struct quadd_cpu_context *cpu_ctx,
-                          struct pt_regs *regs, pid_t pid)
+void quadd_process_mmap(struct vm_area_struct *vma)
 {
-       unsigned long ip;
-       size_t length, length_aligned;
-       struct mm_struct *mm = current->mm;
-       struct vm_area_struct *vma;
        struct file *vm_file;
        struct path *path;
-       char *file_name = NULL;
+       char *file_name, *tmp_buf;
        struct quadd_mmap_data sample;
-       struct quadd_mmap_cpu_ctx *mm_cpu_ctx = this_cpu_ptr(mmap_ctx.cpu_ctx);
-       char *tmp_buf = mm_cpu_ctx->tmp_buf;
+       size_t length, length_aligned;
 
-       if (!mm)
+       if (!vma)
                return;
 
-       ip = instruction_pointer(regs);
-
-       if (user_mode(regs)) {
-               for (vma = find_vma(mm, ip); vma; vma = vma->vm_next) {
-                       if (ip < vma->vm_start || ip >= vma->vm_end)
-                               continue;
-
-                       vm_file = vma->vm_file;
-                       if (!vm_file)
-                               break;
-
-                       path = &vm_file->f_path;
-
-                       file_name = d_path(path, tmp_buf, PATH_MAX);
-                       if (IS_ERR(file_name)) {
-                               file_name = NULL;
-                       } else {
-                               sample.addr = vma->vm_start;
-                               sample.len = vma->vm_end - vma->vm_start;
-                               sample.pgoff = vma->vm_pgoff;
-                       }
-                       break;
-               }
-       } else {
-#ifdef CONFIG_MODULES
-               struct module *mod;
-
-               preempt_disable();
-               mod = __module_address(ip);
-               preempt_enable();
-
-               if (mod) {
-                       file_name = mod->name;
-                       if (file_name) {
-                               sample.addr = (u32) mod->module_core;
-                               sample.len = mod->core_size;
-                               sample.pgoff = 0;
-                       }
-               }
-#endif
-       }
+       if (!(vma->vm_flags & VM_EXEC))
+               return;
 
-       if (file_name) {
-               if (!find_file(file_name, sample.addr, sample.len)) {
-                       length = strlen(file_name) + 1;
-                       if (length > PATH_MAX)
-                               return;
+       vm_file = vma->vm_file;
+       if (!vm_file)
+               return;
 
-                       sample.pid = pid;
+       path = &vm_file->f_path;
 
-                       strcpy(cpu_ctx->mmap_filename, file_name);
-                       length_aligned = ALIGN(length, 8);
+       tmp_buf = kzalloc(PATH_MAX + sizeof(u64), GFP_KERNEL);
+       if (!tmp_buf)
+               return;
 
-                       put_mmap_sample(&sample, cpu_ctx->mmap_filename,
-                                       length_aligned);
-               }
-       }
+       file_name = d_path(path, tmp_buf, PATH_MAX);
+       if (IS_ERR(file_name))
+               goto out;
+
+       if (strstr(file_name, " (deleted)"))
+               goto out;
+
+       sample.addr = vma->vm_start;
+       sample.len = vma->vm_end - vma->vm_start;
+       sample.pgoff = vma->vm_pgoff;
+
+       length = strlen(file_name) + 1;
+       length_aligned = ALIGN(length, sizeof(u64));
+
+       put_mmap_sample(&sample, file_name, length_aligned);
+
+out:
+       kfree(tmp_buf);
 }
 
-int quadd_get_current_mmap(struct quadd_cpu_context *cpu_ctx, pid_t pid)
+int quadd_get_current_mmap(pid_t pid)
 {
        struct vm_area_struct *vma;
        struct file *vm_file;
@@ -230,21 +104,32 @@ int quadd_get_current_mmap(struct quadd_cpu_context *cpu_ctx, pid_t pid)
        struct mm_struct *mm;
        struct quadd_mmap_data sample;
        size_t length, length_aligned;
-       struct quadd_mmap_cpu_ctx *mm_cpu_ctx = this_cpu_ptr(mmap_ctx.cpu_ctx);
-       char *tmp_buf = mm_cpu_ctx->tmp_buf;
+       char *tmp_buf;
 
        rcu_read_lock();
        task = pid_task(find_vpid(pid), PIDTYPE_PID);
        rcu_read_unlock();
        if (!task) {
-               pr_err("Process not found: %u\n", pid);
+               pr_err("Process not found: %d\n", pid);
                return -ESRCH;
        }
+
        mm = task->mm;
+       if (!mm) {
+               pr_warn("mm is not existed for task: %d\n", pid);
+               return 0;
+       }
 
        pr_info("Get mapped memory objects\n");
 
+       tmp_buf = kzalloc(PATH_MAX + sizeof(u64), GFP_KERNEL);
+       if (!tmp_buf)
+               return -ENOMEM;
+
        for (vma = mm->mmap; vma; vma = vma->vm_next) {
+               if (!(vma->vm_flags & VM_EXEC))
+                       continue;
+
                vm_file = vma->vm_file;
                if (!vm_file)
                        continue;
@@ -255,90 +140,20 @@ int quadd_get_current_mmap(struct quadd_cpu_context *cpu_ctx, pid_t pid)
                if (IS_ERR(file_name))
                        continue;
 
-               if (!(vma->vm_flags & VM_EXEC))
+               if (strstr(file_name, " (deleted)"))
                        continue;
 
                length = strlen(file_name) + 1;
-               if (length > PATH_MAX)
-                       continue;
+               length_aligned = ALIGN(length, sizeof(u64));
 
                sample.pid = pid;
                sample.addr = vma->vm_start;
                sample.len = vma->vm_end - vma->vm_start;
                sample.pgoff = vma->vm_pgoff;
 
-               if (!find_file(file_name, sample.addr, sample.len)) {
-                       strcpy(cpu_ctx->mmap_filename, file_name);
-                       length_aligned = ALIGN(length, 8);
-                       put_mmap_sample(&sample, file_name, length_aligned);
-               }
-       }
-       return 0;
-}
-
-struct quadd_mmap_ctx *quadd_mmap_init(struct quadd_ctx *quadd_ctx)
-{
-       int cpu_id;
-       u32 *hash;
-       char *tmp;
-       struct quadd_mmap_cpu_ctx *cpu_ctx;
-
-       mmap_ctx.quadd_ctx = quadd_ctx;
-
-       hash = kzalloc(QUADD_MMAP_SIZE_ARRAY * sizeof(unsigned int),
-                      GFP_KERNEL);
-       if (!hash) {
-               pr_err("Failed to allocate mmap buffer\n");
-               return ERR_PTR(-ENOMEM);
-       }
-       mmap_ctx.hash_array = hash;
-
-       mmap_ctx.nr_hashes = 0;
-       spin_lock_init(&mmap_ctx.lock);
-
-       mmap_ctx.cpu_ctx = alloc_percpu(struct quadd_mmap_cpu_ctx);
-       if (!mmap_ctx.cpu_ctx)
-               return ERR_PTR(-ENOMEM);
-
-       for (cpu_id = 0; cpu_id < nr_cpu_ids; cpu_id++) {
-               cpu_ctx = per_cpu_ptr(mmap_ctx.cpu_ctx, cpu_id);
-
-               tmp = kzalloc(PATH_MAX + sizeof(unsigned long long),
-                             GFP_KERNEL);
-               if (!tmp) {
-                       pr_err("Failed to allocate mmap buffer\n");
-                       return ERR_PTR(-ENOMEM);
-               }
-               cpu_ctx->tmp_buf = tmp;
+               put_mmap_sample(&sample, file_name, length_aligned);
        }
+       kfree(tmp_buf);
 
-       return &mmap_ctx;
-}
-
-void quadd_mmap_reset(void)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&mmap_ctx.lock, flags);
-       mmap_ctx.nr_hashes = 0;
-       spin_unlock_irqrestore(&mmap_ctx.lock, flags);
-}
-
-void quadd_mmap_deinit(void)
-{
-       int cpu_id;
-       unsigned long flags;
-       struct quadd_mmap_cpu_ctx *cpu_ctx;
-
-       spin_lock_irqsave(&mmap_ctx.lock, flags);
-       kfree(mmap_ctx.hash_array);
-       mmap_ctx.hash_array = NULL;
-
-       for (cpu_id = 0; cpu_id < nr_cpu_ids; cpu_id++) {
-               cpu_ctx = per_cpu_ptr(mmap_ctx.cpu_ctx, cpu_id);
-               kfree(cpu_ctx->tmp_buf);
-       }
-       free_percpu(mmap_ctx.cpu_ctx);
-
-       spin_unlock_irqrestore(&mmap_ctx.lock, flags);
+       return 0;
 }
index 4030ed2..51c1500 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * drivers/misc/tegra-profiler/mmap.h
  *
- * Copyright (c) 2013, NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (c) 2014, NVIDIA CORPORATION.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
 
 #include <linux/types.h>
 
-struct quadd_cpu_context;
-struct quadd_ctx;
-struct quadd_mmap_data;
-
-#define QUADD_MMAP_SIZE_ARRAY  4096
-
-struct quadd_mmap_cpu_ctx {
-       char *tmp_buf;
-};
-
-struct quadd_mmap_ctx {
-       u32 *hash_array;
-       unsigned int nr_hashes;
-       spinlock_t lock;
-
-       struct quadd_mmap_cpu_ctx * __percpu cpu_ctx;
-
-       struct quadd_ctx *quadd_ctx;
-};
-
-void quadd_get_mmap_object(struct quadd_cpu_context *cpu_ctx,
-                          struct pt_regs *regs, pid_t pid);
-
-int quadd_get_current_mmap(struct quadd_cpu_context *cpu_ctx, pid_t pid);
-
-struct quadd_mmap_ctx *quadd_mmap_init(struct quadd_ctx *quadd_ctx);
-void quadd_mmap_deinit(void);
-void quadd_mmap_reset(void);
+void quadd_process_mmap(struct vm_area_struct *vma);
+int quadd_get_current_mmap(pid_t pid);
 
 #endif  /* __QUADD_MMAP_H */
index 8e4d591..9de52c7 100644 (file)
@@ -24,7 +24,6 @@
 struct event_data;
 struct quadd_comm_data_interface;
 struct quadd_hrt_ctx;
-struct quadd_mmap_ctx;
 struct quadd_module_state;
 
 struct quadd_event_source_interface {
@@ -57,7 +56,6 @@ struct quadd_ctx {
 
        struct quadd_comm_data_interface *comm;
        struct quadd_hrt_ctx *hrt;
-       struct quadd_mmap_ctx *mmap;
 
        atomic_t started;
        atomic_t tegra_profiler_lock;
index da3f73c..7260267 100644 (file)
@@ -18,7 +18,7 @@
 #ifndef __QUADD_VERSION_H
 #define __QUADD_VERSION_H
 
-#define QUADD_MODULE_VERSION           "1.44"
+#define QUADD_MODULE_VERSION           "1.45"
 #define QUADD_MODULE_BRANCH            "Dev"
 
 #endif /* __QUADD_VERSION_H */
index 28924f5..fd9a2b6 100644 (file)
@@ -351,12 +351,19 @@ struct quadd_module_version {
 
 #pragma pack(pop)
 
+#ifdef __KERNEL__
+
+struct task_struct;
+struct vm_area_struct;
+
 #ifdef CONFIG_TEGRA_PROFILER
 extern void __quadd_task_sched_in(struct task_struct *prev,
                                  struct task_struct *task);
 extern void __quadd_task_sched_out(struct task_struct *prev,
                                   struct task_struct *next);
 
+extern void __quadd_event_mmap(struct vm_area_struct *vma);
+
 static inline void quadd_task_sched_in(struct task_struct *prev,
                                       struct task_struct *task)
 {
@@ -368,7 +375,14 @@ static inline void quadd_task_sched_out(struct task_struct *prev,
 {
        __quadd_task_sched_out(prev, next);
 }
-#else
+
+static inline void quadd_event_mmap(struct vm_area_struct *vma)
+{
+       __quadd_event_mmap(vma);
+}
+
+#else  /* CONFIG_TEGRA_PROFILER */
+
 static inline void quadd_task_sched_in(struct task_struct *prev,
                                       struct task_struct *task)
 {
@@ -378,6 +392,13 @@ static inline void quadd_task_sched_out(struct task_struct *prev,
                                        struct task_struct *next)
 {
 }
-#endif
+
+static inline void quadd_event_mmap(struct vm_area_struct *vma)
+{
+}
+
+#endif /* CONFIG_TEGRA_PROFILER */
+
+#endif /* __KERNEL__ */
 
 #endif  /* __TEGRA_PROFILER_H */
index ed884dd..4c83f85 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -30,6 +30,7 @@
 #include <linux/perf_event.h>
 #include <linux/audit.h>
 #include <linux/khugepaged.h>
+#include <linux/tegra_profiler.h>
 
 #include <asm/uaccess.h>
 #include <asm/cacheflush.h>
@@ -1367,6 +1368,7 @@ munmap_back:
                atomic_inc(&inode->i_writecount);
 out:
        perf_event_mmap(vma);
+       quadd_event_mmap(vma);
 
        mm->total_vm += len >> PAGE_SHIFT;
        vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
@@ -1774,6 +1776,7 @@ int expand_upwards(struct vm_area_struct *vma, unsigned long address)
                        if (!error) {
                                vma->vm_end = address;
                                perf_event_mmap(vma);
+                               quadd_event_mmap(vma);
                        }
                }
        }
@@ -1825,6 +1828,7 @@ int expand_downwards(struct vm_area_struct *vma,
                                vma->vm_start = address;
                                vma->vm_pgoff -= grow;
                                perf_event_mmap(vma);
+                               quadd_event_mmap(vma);
                        }
                }
        }
@@ -2259,6 +2263,8 @@ static unsigned long do_brk(unsigned long addr, unsigned long len)
        vma_link(mm, vma, prev, rb_link, rb_parent);
 out:
        perf_event_mmap(vma);
+       quadd_event_mmap(vma);
+
        mm->total_vm += len >> PAGE_SHIFT;
        if (flags & VM_LOCKED) {
                if (!mlock_vma_pages_range(vma, addr, addr + len))
@@ -2540,6 +2546,7 @@ int install_special_mapping(struct mm_struct *mm,
        mm->total_vm += len >> PAGE_SHIFT;
 
        perf_event_mmap(vma);
+       quadd_event_mmap(vma);
 
        return 0;
 
index a409926..83621b0 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/mmu_notifier.h>
 #include <linux/migrate.h>
 #include <linux/perf_event.h>
+#include <linux/tegra_profiler.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/cacheflush.h>
@@ -222,6 +223,7 @@ success:
        vm_stat_account(mm, oldflags, vma->vm_file, -nrpages);
        vm_stat_account(mm, newflags, vma->vm_file, nrpages);
        perf_event_mmap(vma);
+       quadd_event_mmap(vma);
        return 0;
 
 fail: