[FEATURE] create empty swap_energy module
[kernel/swap-modules.git] / parser / features.c
1 /*
2  *  SWAP Parser
3  *  modules/parser/features.c
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  *
19  * Copyright (C) Samsung Electronics, 2013
20  *
21  * 2013  Vyacheslav Cherkashin: SWAP Parser implement
22  *
23  */
24
25
26 #include <linux/types.h>
27 #include <linux/module.h>
28 #include <ks_features/ks_features.h>
29 #include <us_manager/us_manager.h>
30 #include "parser_defs.h"
31 #include "features.h"
32 #include "msg_parser.h"
33
34 #include <sampler/swap_sampler_module.h>
35 #include <energy/swap_energy.h>
36
37 enum features_list {
38         syscall_file    = (1 << 10),    /* File operation syscalls tracing */
39         syscall_ipc     = (1 << 11),    /* IPC syscall tracing */
40         syscall_process = (1 << 12),    /* Process syscalls tracing */
41         syscall_signal  = (1 << 13),    /* Signal syscalls tracing */
42         syscall_network = (1 << 14),    /* Network syscalls tracing */
43         syscall_desc    = (1 << 15),    /* Descriptor syscalls tracing */
44         context_switch  = (1 << 16),    /* Context switch tracing */
45         func_sampling   = (1 << 19)     /* Function sampling */
46 };
47
48 int set_us_inst(struct conf_data *conf)
49 {
50         int ret;
51
52         ret = usm_start();
53
54         return ret;
55 }
56
57 int unset_us_inst(void)
58 {
59         int ret;
60
61         ret = usm_stop();
62
63         return ret;
64 }
65
66 int set_syscall_file(struct conf_data *conf)
67 {
68         int ret;
69
70         ret = set_feature(FID_FILE);
71
72         return ret;
73 }
74
75 int unset_syscall_file(void)
76 {
77         int ret;
78
79         ret = unset_feature(FID_FILE);
80
81         return ret;
82 }
83
84 int set_syscall_ipc(struct conf_data *conf)
85 {
86         int ret;
87
88         ret = set_feature(FID_IPC);
89
90         return ret;
91 }
92
93 int unset_syscall_ipc(void)
94 {
95         int ret;
96
97         ret = unset_feature(FID_IPC);
98
99         return ret;
100 }
101
102 int set_syscall_process(struct conf_data *conf)
103 {
104         int ret;
105
106         ret = set_feature(FID_PROCESS);
107
108         return ret;
109 }
110
111 int unset_syscall_process(void)
112 {
113         int ret;
114
115         ret = unset_feature(FID_PROCESS);
116
117         return ret;
118 }
119
120 int set_syscall_signal(struct conf_data *conf)
121 {
122         int ret;
123
124         ret = set_feature(FID_SIGNAL);
125
126         return ret;
127 }
128
129 int unset_syscall_signal(void)
130 {
131         int ret;
132
133         ret = unset_feature(FID_SIGNAL);
134
135         return ret;
136 }
137
138 int set_syscall_network(struct conf_data *conf)
139 {
140         int ret;
141
142         ret = set_feature(FID_NET);
143
144         return ret;
145 }
146
147 int unset_syscall_network(void)
148 {
149         int ret;
150
151         ret = unset_feature(FID_NET);
152
153         return ret;
154 }
155
156 int set_syscall_desc(struct conf_data *conf)
157 {
158         int ret;
159
160         ret = set_feature(FID_DESC);
161
162         return ret;
163 }
164
165 int unset_syscall_desc(void)
166 {
167         int ret;
168
169         ret = unset_feature(FID_DESC);
170
171         return ret;
172 }
173
174 int set_context_switch(struct conf_data *conf)
175 {
176         int ret;
177
178         ret = set_feature(FID_SWITCH);
179
180         return ret;
181 }
182
183 int unset_context_switch(void)
184 {
185         int ret;
186
187         ret = unset_feature(FID_SWITCH);
188
189         return ret;
190 }
191
192 int set_func_sampling(struct conf_data *conf)
193 {
194         int ret;
195
196         ret = swap_sampler_start(conf->data_msg_period);
197
198         return ret;
199 }
200
201 int unset_func_sampling(void)
202 {
203         int ret;
204
205         ret = swap_sampler_stop();
206
207         return ret;
208 }
209
210 static int set_func_energy(struct conf_data *conf)
211 {
212         return set_energy();
213 }
214
215 static int unset_func_energy(void)
216 {
217         unset_energy();
218         return 0;
219 }
220
221 struct feature_item {
222         char *name;
223         int (*set)(struct conf_data *conf);
224         int (*unset)(void);
225 };
226
227 static struct feature_item feature_us_inst = {
228         .name = "user space instrumentation",
229         .set = set_us_inst,
230         .unset = unset_us_inst
231 };
232
233 static struct feature_item feature_syscall_file = {
234         .name = "file operation syscalls",
235         .set = set_syscall_file,
236         .unset = unset_syscall_file
237 };
238
239 static struct feature_item feature_syscall_ipc = {
240         .name = "IPC syscall",
241         .set = set_syscall_ipc,
242         .unset = unset_syscall_ipc
243 };
244
245 static struct feature_item feature_syscall_process = {
246         .name = "process syscalls",
247         .set = set_syscall_process,
248         .unset = unset_syscall_process
249 };
250
251 static struct feature_item feature_syscall_signal = {
252         .name = "signal syscalls",
253         .set = set_syscall_signal,
254         .unset = unset_syscall_signal
255 };
256
257 static struct feature_item feature_syscall_network = {
258         .name = "network syscalls",
259         .set = set_syscall_network,
260         .unset = unset_syscall_network
261 };
262
263 static struct feature_item feature_syscall_desc = {
264         .name = "descriptor syscalls",
265         .set = set_syscall_desc,
266         .unset = unset_syscall_desc
267 };
268
269 static struct feature_item feature_context_switch = {
270         .name = "context switch",
271         .set = set_context_switch,
272         .unset = unset_context_switch
273 };
274
275 static struct feature_item feature_func_sampling = {
276         .name = "function sampling",
277         .set = set_func_sampling,
278         .unset = unset_func_sampling
279 };
280
281 static struct feature_item feature_func_energy = {
282         .name = "energy",
283         .set = set_func_energy,
284         .unset = unset_func_energy
285 };
286
287 static struct feature_item *feature_list[] = {
288  /*  0 */       NULL,
289  /*  1 */       NULL,
290  /*  2 */       &feature_us_inst,
291  /*  3 */       NULL,
292  /*  4 */       NULL,
293  /*  5 */       NULL,
294  /*  6 */       NULL,
295  /*  7 */       NULL,
296  /*  8 */       NULL,
297  /*  9 */       NULL,
298  /* 10 */       &feature_syscall_file,
299  /* 11 */       &feature_syscall_ipc,
300  /* 12 */       &feature_syscall_process,
301  /* 13 */       &feature_syscall_signal,
302  /* 14 */       &feature_syscall_network,
303  /* 15 */       &feature_syscall_desc,
304  /* 16 */       &feature_context_switch,
305  /* 17 */       NULL,
306  /* 18 */       NULL,
307  /* 19 */       &feature_func_sampling,
308  /* 20 */       NULL,
309  /* 21 */       NULL,
310  /* 22 */       NULL,
311  /* 23 */       NULL,
312  /* 24 */       NULL,
313  /* 25 */       NULL,
314  /* 26 */       &feature_func_energy
315 };
316
317 enum {
318         SIZE_FEATURE_LIST = sizeof(feature_list) / sizeof(struct feature_item *),
319 };
320
321 static u64 feature_inst = 0;
322 static u64 feature_mask = 0;
323
324 int init_features(void)
325 {
326         int i;
327         for (i = 0; i < SIZE_FEATURE_LIST; ++i) {
328                 printk("### f init_feature_mask[%2d]=%p\n", i, feature_list[i]);
329                 if (feature_list[i] != NULL) {
330                         feature_mask |= ((u64)1) << i;
331                         printk("### f name=%s\n", feature_list[i]->name);
332                 }
333         }
334
335         return 0;
336 }
337
338 void uninit_features(void)
339 {
340 }
341
342 int set_features(struct conf_data *conf)
343 {
344         int i, ret;
345         u64 feature_XOR;
346         u64 features, features_backup;
347
348         /* TODO: field use_features1 is not used*/
349         features_backup = features = conf->use_features0;
350
351         features &= feature_mask;
352         feature_XOR = features ^ feature_inst;
353
354         for (i = 0; feature_XOR && i < SIZE_FEATURE_LIST; ++i) {
355                 if ((feature_XOR & 1) && feature_list[i] != NULL) {
356                         u64 f_mask;
357                         if (features & 1)
358                                 ret = feature_list[i]->set(conf);
359                         else
360                                 ret = feature_list[i]->unset();
361
362                         if (ret) {
363                                 char *func = features & 1 ? "set" : "unset";
364                                 print_err("%s '%s' ret=%d\n",
365                                           func, feature_list[i]->name, ret);
366
367                                 return ret;
368                         }
369                         f_mask = ~(1 << i);
370                         feature_inst = (feature_inst & f_mask) |
371                                        (features_backup & ~f_mask);
372                 }
373
374                 features >>= 1;
375                 feature_XOR >>= 1;
376         }
377
378         return 0;
379 }