a1422cc98445d32cf4aea77e2dd9989034d0dd1e
[linux-2.6.git] / drivers / misc / tegra-profiler / ma.c
1 /*
2  * drivers/misc/tegra-profiler/ma.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/module.h>
20 #include <linux/mm.h>
21 #include <linux/timer.h>
22 #include <linux/sched.h>
23
24 #include <linux/tegra_profiler.h>
25
26 #include "ma.h"
27 #include "quadd.h"
28 #include "hrt.h"
29 #include "comm.h"
30 #include "debug.h"
31
32 static void make_sample(struct quadd_hrt_ctx *hrt_ctx,
33                         pid_t pid, unsigned long vm_size,
34                         unsigned long rss_size)
35 {
36         struct quadd_record_data record;
37         struct quadd_ma_data *ma = &record.ma;
38         struct quadd_comm_data_interface *comm = hrt_ctx->quadd_ctx->comm;
39
40         record.magic = QUADD_RECORD_MAGIC;
41         record.record_type = QUADD_RECORD_TYPE_MA;
42
43         ma->pid = pid;
44         ma->time = quadd_get_time();
45
46         ma->vm_size = vm_size << (PAGE_SHIFT-10);
47         ma->rss_size = rss_size << (PAGE_SHIFT-10);
48
49         comm->put_sample(&record, NULL, 0);
50 }
51
52 static void check_ma(struct quadd_hrt_ctx *hrt_ctx)
53 {
54         pid_t pid;
55         struct pid *pid_s;
56         struct task_struct *task = NULL;
57         struct mm_struct *mm;
58         struct quadd_ctx *quadd_ctx = hrt_ctx->quadd_ctx;
59         unsigned long vm_size, rss_size, total_vm;
60
61         pid = quadd_ctx->param.pids[0];
62
63         rcu_read_lock();
64         pid_s = find_vpid(pid);
65         if (pid_s)
66                 task = pid_task(pid_s, PIDTYPE_PID);
67         rcu_read_unlock();
68         if (!task)
69                 return;
70
71         mm = task->mm;
72         if (!mm)
73                 return;
74
75         total_vm = mm->total_vm;
76         vm_size = total_vm - mm->reserved_vm;
77         rss_size = get_mm_rss(mm);
78
79         if (vm_size != hrt_ctx->vm_size_prev ||
80             rss_size != hrt_ctx->rss_size_prev) {
81                 make_sample(hrt_ctx, pid, vm_size, rss_size);
82                 hrt_ctx->vm_size_prev = vm_size;
83                 hrt_ctx->rss_size_prev = rss_size;
84         }
85 }
86
87 static void timer_interrupt(unsigned long data)
88 {
89         struct quadd_hrt_ctx *hrt_ctx = (struct quadd_hrt_ctx *)data;
90         struct timer_list *timer = &hrt_ctx->ma_timer;
91
92         if (hrt_ctx->active == 0)
93                 return;
94
95         check_ma(hrt_ctx);
96
97         timer->expires = jiffies + msecs_to_jiffies(hrt_ctx->ma_period);
98         add_timer(timer);
99 }
100
101 void quadd_ma_start(struct quadd_hrt_ctx *hrt_ctx)
102 {
103         struct timer_list *timer = &hrt_ctx->ma_timer;
104
105         if (hrt_ctx->ma_period == 0) {
106                 pr_info("QuadD MA is disabled\n");
107                 return;
108         }
109         pr_info("QuadD MA is started, interval: %u msec\n",
110                 hrt_ctx->ma_period);
111
112         hrt_ctx->vm_size_prev = 0;
113         hrt_ctx->rss_size_prev = 0;
114
115         init_timer(timer);
116         timer->function = timer_interrupt;
117         timer->expires = jiffies + msecs_to_jiffies(hrt_ctx->ma_period);
118         timer->data = (unsigned long)hrt_ctx;
119         add_timer(timer);
120 }
121
122 void quadd_ma_stop(struct quadd_hrt_ctx *hrt_ctx)
123 {
124         if (hrt_ctx->ma_period > 0) {
125                 pr_info("QuadD MA is stopped\n");
126                 del_timer_sync(&hrt_ctx->ma_timer);
127         }
128 }