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>
8 #define CREATE_TRACE_POINTS
9 #include <trace/events/mm_event.h>
11 static unsigned long period_ms
= 500;
13 void mm_event_task_init(struct task_struct
*tsk
)
15 memset(tsk
->mm_event
, 0, sizeof(tsk
->mm_event
));
19 static void record_stat(void)
21 if (time_is_before_eq_jiffies(current
->next_period
)) {
24 for (i
= 0; i
< MM_TYPE_NUM
; i
++) {
25 if (current
->mm_event
[i
].count
== 0)
28 trace_mm_event_record(i
, ¤t
->mm_event
[i
]);
29 memset(¤t
->mm_event
[i
], 0,
30 sizeof(struct mm_event_task
));
32 current
->next_period
= jiffies
+ msecs_to_jiffies(period_ms
);
36 void mm_event_start(ktime_t
*time
)
41 void mm_event_end(enum mm_event_type event
, ktime_t start
)
43 s64 elapsed
= ktime_us_delta(ktime_get(), start
);
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
;
52 static struct dentry
*mm_event_root
;
54 static int period_ms_set(void *data
, u64 val
)
56 if (val
< 1 || val
> ULONG_MAX
)
59 period_ms
= (unsigned long)val
;
63 static int period_ms_get(void *data
, u64
*val
)
69 DEFINE_SIMPLE_ATTRIBUTE(period_ms_operations
, period_ms_get
,
70 period_ms_set
, "%llu\n");
72 static int __init
mm_event_init(void)
76 mm_event_root
= debugfs_create_dir("mm_event", NULL
);
78 pr_warn("debugfs dir <mm_event> creation failed\n");
79 return PTR_ERR(mm_event_root
);
82 entry
= debugfs_create_file("period_ms", 0644,
83 mm_event_root
, NULL
, &period_ms_operations
);
86 pr_warn("debugfs file mm_event_task creation failed\n");
87 debugfs_remove_recursive(mm_event_root
);
88 return PTR_ERR(entry
);
93 subsys_initcall(mm_event_init
);