diff options
author | Igor Nabirushkin <inabirushkin@nvidia.com> | 2014-01-27 03:13:33 +0400 |
---|---|---|
committer | Bharat Nihalani <bnihalani@nvidia.com> | 2014-02-07 06:11:38 -0800 |
commit | 4a37f8b0dbc1763f8a992d2c126258ea3190e529 (patch) | |
tree | 5507527b3ec1875d4b79ca49b241ecc03c955ed6 /drivers/misc/tegra-profiler/mmap.c | |
parent | de7bfbdf663e5ca00ba44e3575d5deaddbfea4cd (diff) |
misc: tegra-profiler: use mmap calls
Tegra Profiler: add mmap calls
Bug 1447662
Change-Id: I96614ab3c320fd028cf861ea970b5199bdcae1c7
Signed-off-by: Igor Nabirushkin <inabirushkin@nvidia.com>
Reviewed-on: http://git-master/r/360152
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Tested-by: Bharat Nihalani <bnihalani@nvidia.com>
Diffstat (limited to 'drivers/misc/tegra-profiler/mmap.c')
-rw-r--r-- | drivers/misc/tegra-profiler/mmap.c | 291 |
1 files changed, 53 insertions, 238 deletions
diff --git a/drivers/misc/tegra-profiler/mmap.c b/drivers/misc/tegra-profiler/mmap.c index bcec4b32fb24..81abf36c7145 100644 --- a/drivers/misc/tegra-profiler/mmap.c +++ b/drivers/misc/tegra-profiler/mmap.c @@ -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> @@ -29,98 +27,6 @@ #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; } |