mm: mm_event: make capture period configurable
[GitHub/LineageOS/android_kernel_motorola_exynos9610.git] / mm / mm_event.c
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>
10 /* msec */
11 static unsigned long period_ms = 500;
12
13 void 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
19 static 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 }
32 current->next_period = jiffies + msecs_to_jiffies(period_ms);
33 }
34 }
35
36 void mm_event_start(ktime_t *time)
37 {
38 *time = ktime_get();
39 }
40
41 void 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
52 static struct dentry *mm_event_root;
53
54 static int period_ms_set(void *data, u64 val)
55 {
56 if (val < 1 || val > ULONG_MAX)
57 return -EINVAL;
58
59 period_ms = (unsigned long)val;
60 return 0;
61 }
62
63 static int period_ms_get(void *data, u64 *val)
64 {
65 *val = period_ms;
66 return 0;
67 }
68
69 DEFINE_SIMPLE_ATTRIBUTE(period_ms_operations, period_ms_get,
70 period_ms_set, "%llu\n");
71
72 static int __init mm_event_init(void)
73 {
74 struct dentry *entry;
75
76 mm_event_root = debugfs_create_dir("mm_event", NULL);
77 if (!mm_event_root) {
78 pr_warn("debugfs dir <mm_event> creation failed\n");
79 return PTR_ERR(mm_event_root);
80 }
81
82 entry = debugfs_create_file("period_ms", 0644,
83 mm_event_root, NULL, &period_ms_operations);
84
85 if (IS_ERR(entry)) {
86 pr_warn("debugfs file mm_event_task creation failed\n");
87 debugfs_remove_recursive(mm_event_root);
88 return PTR_ERR(entry);
89 }
90
91 return 0;
92 }
93 subsys_initcall(mm_event_init);