]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/blob - drivers/misc/tegra-profiler/mmap.c
misc: tegra-profiler: use mmap calls
[sojka/nv-tegra/linux-3.10.git] / drivers / misc / tegra-profiler / mmap.c
1 /*
2  * drivers/misc/tegra-profiler/mmap.c
3  *
4  * Copyright (c) 2014, NVIDIA CORPORATION.  All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  */
16
17 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18
19 #include <linux/mm.h>
20 #include <linux/fs.h>
21 #include <linux/slab.h>
22 #include <linux/err.h>
23 #include <linux/sched.h>
24
25 #include <linux/tegra_profiler.h>
26
27 #include "mmap.h"
28 #include "comm.h"
29 #include "hrt.h"
30
31 static void
32 put_mmap_sample(struct quadd_mmap_data *s, char *filename,
33                 size_t length)
34 {
35         struct quadd_record_data r;
36         struct quadd_iovec vec;
37
38         r.magic = QUADD_RECORD_MAGIC;
39         r.record_type = QUADD_RECORD_TYPE_MMAP;
40
41         memcpy(&r.mmap, s, sizeof(*s));
42         r.mmap.filename_length = length;
43
44         vec.base = filename;
45         vec.len = length;
46
47         pr_debug("MMAP: pid: %u, file_name: '%s', addr: %#llx - %#llx, len: %llx, pgoff: %#x\n",
48                 s->pid, filename, s->addr, s->addr + s->len, s->len, s->pgoff);
49
50         quadd_put_sample(&r, &vec, 1);
51 }
52
53 void quadd_process_mmap(struct vm_area_struct *vma)
54 {
55         struct file *vm_file;
56         struct path *path;
57         char *file_name, *tmp_buf;
58         struct quadd_mmap_data sample;
59         size_t length, length_aligned;
60
61         if (!vma)
62                 return;
63
64         if (!(vma->vm_flags & VM_EXEC))
65                 return;
66
67         vm_file = vma->vm_file;
68         if (!vm_file)
69                 return;
70
71         path = &vm_file->f_path;
72
73         tmp_buf = kzalloc(PATH_MAX + sizeof(u64), GFP_KERNEL);
74         if (!tmp_buf)
75                 return;
76
77         file_name = d_path(path, tmp_buf, PATH_MAX);
78         if (IS_ERR(file_name))
79                 goto out;
80
81         if (strstr(file_name, " (deleted)"))
82                 goto out;
83
84         sample.addr = vma->vm_start;
85         sample.len = vma->vm_end - vma->vm_start;
86         sample.pgoff = vma->vm_pgoff;
87
88         length = strlen(file_name) + 1;
89         length_aligned = ALIGN(length, sizeof(u64));
90
91         put_mmap_sample(&sample, file_name, length_aligned);
92
93 out:
94         kfree(tmp_buf);
95 }
96
97 int quadd_get_current_mmap(pid_t pid)
98 {
99         struct vm_area_struct *vma;
100         struct file *vm_file;
101         struct path *path;
102         char *file_name;
103         struct task_struct *task;
104         struct mm_struct *mm;
105         struct quadd_mmap_data sample;
106         size_t length, length_aligned;
107         char *tmp_buf;
108
109         rcu_read_lock();
110         task = pid_task(find_vpid(pid), PIDTYPE_PID);
111         rcu_read_unlock();
112         if (!task) {
113                 pr_err("Process not found: %d\n", pid);
114                 return -ESRCH;
115         }
116
117         mm = task->mm;
118         if (!mm) {
119                 pr_warn("mm is not existed for task: %d\n", pid);
120                 return 0;
121         }
122
123         pr_info("Get mapped memory objects\n");
124
125         tmp_buf = kzalloc(PATH_MAX + sizeof(u64), GFP_KERNEL);
126         if (!tmp_buf)
127                 return -ENOMEM;
128
129         for (vma = mm->mmap; vma; vma = vma->vm_next) {
130                 if (!(vma->vm_flags & VM_EXEC))
131                         continue;
132
133                 vm_file = vma->vm_file;
134                 if (!vm_file)
135                         continue;
136
137                 path = &vm_file->f_path;
138
139                 file_name = d_path(path, tmp_buf, PATH_MAX);
140                 if (IS_ERR(file_name))
141                         continue;
142
143                 if (strstr(file_name, " (deleted)"))
144                         continue;
145
146                 length = strlen(file_name) + 1;
147                 length_aligned = ALIGN(length, sizeof(u64));
148
149                 sample.pid = pid;
150                 sample.addr = vma->vm_start;
151                 sample.len = vma->vm_end - vma->vm_start;
152                 sample.pgoff = vma->vm_pgoff;
153
154                 put_mmap_sample(&sample, file_name, length_aligned);
155         }
156         kfree(tmp_buf);
157
158         return 0;
159 }