mm: mm_event: add special kernel allocation stat
[GitHub/LineageOS/android_kernel_motorola_exynos9610.git] / mm / mm_event.c
CommitLineData
be075489
MK
1#include <linux/mm.h>
2#include <linux/mm_event.h>
3#include <linux/sched.h>
4#include <linux/vmalloc.h>
5#include <linux/seq_file.h>
6#include <linux/debugfs.h>
7
8#define CREATE_TRACE_POINTS
9#include <trace/events/mm_event.h>
d2a22b87
MK
10/* msec */
11static unsigned long period_ms = 500;
be075489
MK
12
13void mm_event_task_init(struct task_struct *tsk)
14{
15 memset(tsk->mm_event, 0, sizeof(tsk->mm_event));
16 tsk->next_period = 0;
17}
18
19static void record_stat(void)
20{
21 if (time_is_before_eq_jiffies(current->next_period)) {
22 int i;
23
24 for (i = 0; i < MM_TYPE_NUM; i++) {
25 if (current->mm_event[i].count == 0)
26 continue;
27
28 trace_mm_event_record(i, &current->mm_event[i]);
29 memset(&current->mm_event[i], 0,
30 sizeof(struct mm_event_task));
31 }
d2a22b87 32 current->next_period = jiffies + msecs_to_jiffies(period_ms);
be075489
MK
33 }
34}
35
36void mm_event_start(ktime_t *time)
37{
38 *time = ktime_get();
39}
40
41void mm_event_end(enum mm_event_type event, ktime_t start)
42{
43 s64 elapsed = ktime_us_delta(ktime_get(), start);
44
45 current->mm_event[event].count++;
46 current->mm_event[event].accm_lat += elapsed;
47 if (elapsed > current->mm_event[event].max_lat)
48 current->mm_event[event].max_lat = elapsed;
49 record_stat();
50}
51
cee78bb6
MK
52void mm_event_count(enum mm_event_type event, int count)
53{
54 current->mm_event[event].count += count;
55 record_stat();
56}
57
be075489
MK
58static struct dentry *mm_event_root;
59
d2a22b87
MK
60static int period_ms_set(void *data, u64 val)
61{
62 if (val < 1 || val > ULONG_MAX)
63 return -EINVAL;
64
65 period_ms = (unsigned long)val;
66 return 0;
67}
68
69static int period_ms_get(void *data, u64 *val)
70{
71 *val = period_ms;
72 return 0;
73}
74
75DEFINE_SIMPLE_ATTRIBUTE(period_ms_operations, period_ms_get,
76 period_ms_set, "%llu\n");
77
be075489
MK
78static int __init mm_event_init(void)
79{
d2a22b87
MK
80 struct dentry *entry;
81
be075489
MK
82 mm_event_root = debugfs_create_dir("mm_event", NULL);
83 if (!mm_event_root) {
84 pr_warn("debugfs dir <mm_event> creation failed\n");
85 return PTR_ERR(mm_event_root);
86 }
87
d2a22b87
MK
88 entry = debugfs_create_file("period_ms", 0644,
89 mm_event_root, NULL, &period_ms_operations);
90
91 if (IS_ERR(entry)) {
92 pr_warn("debugfs file mm_event_task creation failed\n");
93 debugfs_remove_recursive(mm_event_root);
94 return PTR_ERR(entry);
95 }
96
be075489
MK
97 return 0;
98}
99subsys_initcall(mm_event_init);