]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - android-sdk/arm-ds5-gator.git/blob - driver/gator_events_meminfo.c
gator-driver: Disable event-base sampling support
[android-sdk/arm-ds5-gator.git] / driver / gator_events_meminfo.c
1 /**
2  * Copyright (C) ARM Limited 2010-2011. All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  */
10 #include "gator.h"
11 #include <linux/workqueue.h>
12 #include <trace/events/kmem.h>
14 #define MEMINFO_MEMFREE         0
15 #define MEMINFO_MEMUSED         1
16 #define MEMINFO_BUFFERRAM       2
17 #define MEMINFO_TOTAL           3
19 static ulong meminfo_global_enabled;
20 static ulong meminfo_enabled[MEMINFO_TOTAL];
21 static ulong meminfo_key[MEMINFO_TOTAL];
22 static unsigned long long meminfo_buffer[MEMINFO_TOTAL * 2];
23 static int meminfo_length = 0;
24 static unsigned int mem_event = 0;
25 static bool new_data_avail;
27 static void wq_sched_handler(struct work_struct *wsptr);
29 DECLARE_WORK(work, wq_sched_handler);
31 GATOR_DEFINE_PROBE(mm_page_free_direct, TP_PROTO(struct page *page, unsigned int order)) {
32         mem_event++;
33 }
35 GATOR_DEFINE_PROBE(mm_pagevec_free, TP_PROTO(struct page *page, int cold)) {
36         mem_event++;
37 }
39 GATOR_DEFINE_PROBE(mm_page_alloc, TP_PROTO(struct page *page, unsigned int order, gfp_t gfp_flags, int migratetype)) {
40         mem_event++;
41 }
43 static int gator_events_meminfo_create_files(struct super_block *sb, struct dentry *root)
44 {
45         struct dentry *dir;
46         int i;
48         for (i = 0; i < MEMINFO_TOTAL; i++) {
49                 switch (i) {
50                 case MEMINFO_MEMFREE:
51                         dir = gatorfs_mkdir(sb, root, "Linux_meminfo_memfree");
52                         break;
53                 case MEMINFO_MEMUSED:
54                         dir = gatorfs_mkdir(sb, root, "Linux_meminfo_memused");
55                         break;
56                 case MEMINFO_BUFFERRAM:
57                         dir = gatorfs_mkdir(sb, root, "Linux_meminfo_bufferram");
58                         break;
59                 default:
60                         return -1;
61                 }
62                 if (!dir) {
63                         return -1;
64                 }
65                 gatorfs_create_ulong(sb, dir, "enabled", &meminfo_enabled[i]);
66                 gatorfs_create_ro_ulong(sb, dir, "key", &meminfo_key[i]);
67         }
69         return 0;
70 }
72 static int gator_events_meminfo_start(void)
73 {
74         int i;
76         new_data_avail = true;
77         for (i = 0; i < MEMINFO_TOTAL; i++) {
78                 if (meminfo_enabled[i]) {
79                         meminfo_global_enabled = 1;
80                 }
81         }
83         if (meminfo_global_enabled == 0)
84                 return 0;
86         if (GATOR_REGISTER_TRACE(mm_page_free_direct))
87                 goto mm_page_free_direct_exit;
88         if (GATOR_REGISTER_TRACE(mm_pagevec_free))
89                 goto mm_pagevec_free_exit;
90         if (GATOR_REGISTER_TRACE(mm_page_alloc))
91                 goto mm_page_alloc_exit;
93         return 0;
95 mm_page_alloc_exit:
96         GATOR_UNREGISTER_TRACE(mm_pagevec_free);
97 mm_pagevec_free_exit:
98         GATOR_UNREGISTER_TRACE(mm_page_free_direct);
99 mm_page_free_direct_exit:
100         return -1;
103 static void gator_events_meminfo_stop(void)
105         int i;
107         if (meminfo_global_enabled) {
108                 GATOR_UNREGISTER_TRACE(mm_page_free_direct);
109                 GATOR_UNREGISTER_TRACE(mm_pagevec_free);
110                 GATOR_UNREGISTER_TRACE(mm_page_alloc);
111         }
113         meminfo_global_enabled = 0;
114         for (i = 0; i < MEMINFO_TOTAL; i++) {
115                 meminfo_enabled[i] = 0;
116         }
119 // Must be run in a work queue as the kernel function si_meminfo() can sleep
120 static void wq_sched_handler(struct work_struct *wsptr)
122         struct sysinfo info;
123         int i, len;
124         unsigned long long value;
126         meminfo_length = len = 0;
128         si_meminfo(&info);
129         for (i = 0; i < MEMINFO_TOTAL; i++) {
130                 if (meminfo_enabled[i]) {
131                         switch (i) {
132                         case MEMINFO_MEMFREE:
133                                 value = info.freeram * PAGE_SIZE;
134                                 break;
135                         case MEMINFO_MEMUSED:
136                                 value = (info.totalram - info.freeram) * PAGE_SIZE;
137                                 break;
138                         case MEMINFO_BUFFERRAM:
139                                 value = info.bufferram * PAGE_SIZE;
140                                 break;
141                         default:
142                                 value = 0;
143                                 break;
144                         }
145                         meminfo_buffer[len++] = (unsigned long long)meminfo_key[i];
146                         meminfo_buffer[len++] = value;
147                 }
148         }
150         meminfo_length = len;
151         new_data_avail = true;
154 static int gator_events_meminfo_read(long long **buffer)
156         static unsigned int last_mem_event = 0;
158         if (smp_processor_id() || !meminfo_global_enabled)
159                 return 0;
161         if (last_mem_event != mem_event) {
162                 last_mem_event = mem_event;
163                 schedule_work(&work);
164         }
166         if (!new_data_avail)
167                 return 0;
169         new_data_avail = false;
171         if (buffer)
172                 *buffer = meminfo_buffer;
174         return meminfo_length;
177 static struct gator_interface gator_events_meminfo_interface = {
178         .create_files = gator_events_meminfo_create_files,
179         .start = gator_events_meminfo_start,
180         .stop = gator_events_meminfo_stop,
181         .read64 = gator_events_meminfo_read,
182 };
184 int gator_events_meminfo_init(void)
186         int i;
188         meminfo_global_enabled = 0;
189         for (i = 0; i < MEMINFO_TOTAL; i++) {
190                 meminfo_enabled[i] = 0;
191                 meminfo_key[i] = gator_events_get_key();
192         }
194         return gator_events_install(&gator_events_meminfo_interface);
196 gator_events_init(gator_events_meminfo_init);