|
9 | 9 | # Documentation/trace/rv/da_monitor_synthesis.rst |
10 | 10 |
|
11 | 11 | from .dot2c import Dot2c |
12 | | -import platform |
13 | | -import os |
| 12 | +from .generator import Monitor |
14 | 13 |
|
15 | | -class dot2k(Dot2c): |
16 | | - monitor_types = { "global" : 1, "per_cpu" : 2, "per_task" : 3 } |
17 | | - rv_dir = "kernel/trace/rv" |
18 | | - monitor_type = "per_cpu" |
19 | 14 |
|
20 | | - def __init__(self, file_path, MonitorType, extra_params={}): |
21 | | - self.container = extra_params.get("subcmd") == "container" |
22 | | - self.parent = extra_params.get("parent") |
23 | | - if self.container: |
24 | | - self.abs_template_dir = os.path.join(os.path.dirname(__file__), "templates/container") |
25 | | - else: |
26 | | - self.abs_template_dir = os.path.join(os.path.dirname(__file__), "templates/dot2k") |
27 | | - |
28 | | - if self.container: |
29 | | - if file_path: |
30 | | - raise ValueError("A container does not require a dot file") |
31 | | - if MonitorType: |
32 | | - raise ValueError("A container does not require a monitor type") |
33 | | - if self.parent: |
34 | | - raise ValueError("A container cannot have a parent") |
35 | | - self.name = extra_params.get("model_name") |
36 | | - self.events = [] |
37 | | - self.states = [] |
38 | | - self.main_h = self._read_template_file("main.h") |
39 | | - else: |
40 | | - super().__init__(file_path, extra_params.get("model_name")) |
| 15 | +class dot2k(Monitor, Dot2c): |
| 16 | + template_dir = "dot2k" |
41 | 17 |
|
42 | | - self.monitor_type = self.monitor_types.get(MonitorType) |
43 | | - if self.monitor_type is None: |
44 | | - raise ValueError("Unknown monitor type: %s" % MonitorType) |
45 | | - self.monitor_type = MonitorType |
46 | | - self.trace_h = self._read_template_file("trace.h") |
47 | | - |
48 | | - self.main_c = self._read_template_file("main.c") |
49 | | - self.kconfig = self._read_template_file("Kconfig") |
| 18 | + def __init__(self, file_path, MonitorType, extra_params={}): |
| 19 | + self.monitor_type = MonitorType |
| 20 | + Monitor.__init__(self, extra_params) |
| 21 | + Dot2c.__init__(self, file_path, extra_params.get("model_name")) |
50 | 22 | self.enum_suffix = "_%s" % self.name |
51 | | - self.description = extra_params.get("description", self.name) or "auto-generated" |
52 | | - self.auto_patch = extra_params.get("auto_patch") |
53 | | - if self.auto_patch: |
54 | | - self.__fill_rv_kernel_dir() |
55 | | - |
56 | | - def __fill_rv_kernel_dir(self): |
57 | | - |
58 | | - # first try if we are running in the kernel tree root |
59 | | - if os.path.exists(self.rv_dir): |
60 | | - return |
61 | | - |
62 | | - # offset if we are running inside the kernel tree from verification/dot2 |
63 | | - kernel_path = os.path.join("../..", self.rv_dir) |
64 | | - |
65 | | - if os.path.exists(kernel_path): |
66 | | - self.rv_dir = kernel_path |
67 | | - return |
68 | | - |
69 | | - if platform.system() != "Linux": |
70 | | - raise OSError("I can only run on Linux.") |
71 | | - |
72 | | - kernel_path = os.path.join("/lib/modules/%s/build" % platform.release(), self.rv_dir) |
73 | | - |
74 | | - # if the current kernel is from a distro this may not be a full kernel tree |
75 | | - # verify that one of the files we are going to modify is available |
76 | | - if os.path.exists(os.path.join(kernel_path, "rv_trace.h")): |
77 | | - self.rv_dir = kernel_path |
78 | | - return |
79 | | - |
80 | | - raise FileNotFoundError("Could not find the rv directory, do you have the kernel source installed?") |
81 | | - |
82 | | - def __read_file(self, path): |
83 | | - try: |
84 | | - fd = open(path, 'r') |
85 | | - except OSError: |
86 | | - raise Exception("Cannot open the file: %s" % path) |
87 | | - |
88 | | - content = fd.read() |
89 | | - |
90 | | - fd.close() |
91 | | - return content |
92 | | - |
93 | | - def _read_template_file(self, file): |
94 | | - try: |
95 | | - path = os.path.join(self.abs_template_dir, file) |
96 | | - return self.__read_file(path) |
97 | | - except Exception: |
98 | | - # Specific template file not found. Try the generic template file in the template/ |
99 | | - # directory, which is one level up |
100 | | - path = os.path.join(self.abs_template_dir, "..", file) |
101 | | - return self.__read_file(path) |
102 | 23 |
|
103 | 24 | def fill_monitor_type(self): |
104 | 25 | return self.monitor_type.upper() |
105 | 26 |
|
106 | | - def fill_parent(self): |
107 | | - return "&rv_%s" % self.parent if self.parent else "NULL" |
108 | | - |
109 | | - def fill_include_parent(self): |
110 | | - if self.parent: |
111 | | - return "#include <monitors/%s/%s.h>\n" % (self.parent, self.parent) |
112 | | - return "" |
113 | | - |
114 | 27 | def fill_tracepoint_handlers_skel(self): |
115 | 28 | buff = [] |
116 | 29 | for event in self.events: |
@@ -144,30 +57,6 @@ def fill_tracepoint_detach_helper(self): |
144 | 57 | buff.append("\trv_detach_trace_probe(\"%s\", /* XXX: tracepoint */, handle_%s);" % (self.name, event)) |
145 | 58 | return '\n'.join(buff) |
146 | 59 |
|
147 | | - def fill_main_c(self): |
148 | | - main_c = self.main_c |
149 | | - monitor_type = self.fill_monitor_type() |
150 | | - min_type = self.get_minimun_type() |
151 | | - nr_events = len(self.events) |
152 | | - tracepoint_handlers = self.fill_tracepoint_handlers_skel() |
153 | | - tracepoint_attach = self.fill_tracepoint_attach_probe() |
154 | | - tracepoint_detach = self.fill_tracepoint_detach_helper() |
155 | | - parent = self.fill_parent() |
156 | | - parent_include = self.fill_include_parent() |
157 | | - |
158 | | - main_c = main_c.replace("%%MONITOR_TYPE%%", monitor_type) |
159 | | - main_c = main_c.replace("%%MIN_TYPE%%", min_type) |
160 | | - main_c = main_c.replace("%%MODEL_NAME%%", self.name) |
161 | | - main_c = main_c.replace("%%NR_EVENTS%%", str(nr_events)) |
162 | | - main_c = main_c.replace("%%TRACEPOINT_HANDLERS_SKEL%%", tracepoint_handlers) |
163 | | - main_c = main_c.replace("%%TRACEPOINT_ATTACH%%", tracepoint_attach) |
164 | | - main_c = main_c.replace("%%TRACEPOINT_DETACH%%", tracepoint_detach) |
165 | | - main_c = main_c.replace("%%DESCRIPTION%%", self.description) |
166 | | - main_c = main_c.replace("%%PARENT%%", parent) |
167 | | - main_c = main_c.replace("%%INCLUDE_PARENT%%", parent_include) |
168 | | - |
169 | | - return main_c |
170 | | - |
171 | 60 | def fill_model_h_header(self): |
172 | 61 | buff = [] |
173 | 62 | buff.append("/* SPDX-License-Identifier: GPL-2.0 */") |
@@ -226,147 +115,15 @@ def fill_tracepoint_args_skel(self, tp_type): |
226 | 115 | buff.append(" TP_ARGS(%s)" % tp_args_c) |
227 | 116 | return '\n'.join(buff) |
228 | 117 |
|
229 | | - def fill_monitor_deps(self): |
230 | | - buff = [] |
231 | | - buff.append(" # XXX: add dependencies if there") |
232 | | - if self.parent: |
233 | | - buff.append(" depends on RV_MON_%s" % self.parent.upper()) |
234 | | - buff.append(" default y") |
235 | | - return '\n'.join(buff) |
236 | | - |
237 | | - def fill_trace_h(self): |
238 | | - trace_h = self.trace_h |
239 | | - monitor_class = self.fill_monitor_class() |
240 | | - monitor_class_type = self.fill_monitor_class_type() |
241 | | - tracepoint_args_skel_event = self.fill_tracepoint_args_skel("event") |
242 | | - tracepoint_args_skel_error = self.fill_tracepoint_args_skel("error") |
243 | | - trace_h = trace_h.replace("%%MODEL_NAME%%", self.name) |
244 | | - trace_h = trace_h.replace("%%MODEL_NAME_UP%%", self.name.upper()) |
245 | | - trace_h = trace_h.replace("%%MONITOR_CLASS%%", monitor_class) |
246 | | - trace_h = trace_h.replace("%%MONITOR_CLASS_TYPE%%", monitor_class_type) |
247 | | - trace_h = trace_h.replace("%%TRACEPOINT_ARGS_SKEL_EVENT%%", tracepoint_args_skel_event) |
248 | | - trace_h = trace_h.replace("%%TRACEPOINT_ARGS_SKEL_ERROR%%", tracepoint_args_skel_error) |
249 | | - return trace_h |
250 | | - |
251 | | - def fill_kconfig(self): |
252 | | - kconfig = self.kconfig |
253 | | - monitor_class_type = self.fill_monitor_class_type() |
254 | | - monitor_deps = self.fill_monitor_deps() |
255 | | - kconfig = kconfig.replace("%%MODEL_NAME%%", self.name) |
256 | | - kconfig = kconfig.replace("%%MODEL_NAME_UP%%", self.name.upper()) |
257 | | - kconfig = kconfig.replace("%%MONITOR_CLASS_TYPE%%", monitor_class_type) |
258 | | - kconfig = kconfig.replace("%%DESCRIPTION%%", self.description) |
259 | | - kconfig = kconfig.replace("%%MONITOR_DEPS%%", monitor_deps) |
260 | | - return kconfig |
261 | | - |
262 | | - def fill_main_container_h(self): |
263 | | - main_h = self.main_h |
264 | | - main_h = main_h.replace("%%MODEL_NAME%%", self.name) |
265 | | - return main_h |
266 | | - |
267 | | - def __patch_file(self, file, marker, line): |
268 | | - file_to_patch = os.path.join(self.rv_dir, file) |
269 | | - content = self.__read_file(file_to_patch) |
270 | | - content = content.replace(marker, line + "\n" + marker) |
271 | | - self.__write_file(file_to_patch, content) |
272 | | - |
273 | | - def fill_tracepoint_tooltip(self): |
274 | | - monitor_class_type = self.fill_monitor_class_type() |
275 | | - if self.auto_patch: |
276 | | - self.__patch_file("rv_trace.h", |
277 | | - "// Add new monitors based on CONFIG_%s here" % monitor_class_type, |
278 | | - "#include <monitors/%s/%s_trace.h>" % (self.name, self.name)) |
279 | | - return " - Patching %s/rv_trace.h, double check the result" % self.rv_dir |
280 | | - |
281 | | - return """ - Edit %s/rv_trace.h: |
282 | | -Add this line where other tracepoints are included and %s is defined: |
283 | | -#include <monitors/%s/%s_trace.h> |
284 | | -""" % (self.rv_dir, monitor_class_type, self.name, self.name) |
285 | | - |
286 | | - def fill_kconfig_tooltip(self): |
287 | | - if self.auto_patch: |
288 | | - self.__patch_file("Kconfig", |
289 | | - "# Add new monitors here", |
290 | | - "source \"kernel/trace/rv/monitors/%s/Kconfig\"" % (self.name)) |
291 | | - return " - Patching %s/Kconfig, double check the result" % self.rv_dir |
292 | | - |
293 | | - return """ - Edit %s/Kconfig: |
294 | | -Add this line where other monitors are included: |
295 | | -source \"kernel/trace/rv/monitors/%s/Kconfig\" |
296 | | -""" % (self.rv_dir, self.name) |
297 | | - |
298 | | - def fill_makefile_tooltip(self): |
299 | | - name = self.name |
300 | | - name_up = name.upper() |
301 | | - if self.auto_patch: |
302 | | - self.__patch_file("Makefile", |
303 | | - "# Add new monitors here", |
304 | | - "obj-$(CONFIG_RV_MON_%s) += monitors/%s/%s.o" % (name_up, name, name)) |
305 | | - return " - Patching %s/Makefile, double check the result" % self.rv_dir |
306 | | - |
307 | | - return """ - Edit %s/Makefile: |
308 | | -Add this line where other monitors are included: |
309 | | -obj-$(CONFIG_RV_MON_%s) += monitors/%s/%s.o |
310 | | -""" % (self.rv_dir, name_up, name, name) |
311 | | - |
312 | | - def fill_monitor_tooltip(self): |
313 | | - if self.auto_patch: |
314 | | - return " - Monitor created in %s/monitors/%s" % (self.rv_dir, self. name) |
315 | | - return " - Move %s/ to the kernel's monitor directory (%s/monitors)" % (self.name, self.rv_dir) |
316 | | - |
317 | | - def __create_directory(self): |
318 | | - path = self.name |
319 | | - if self.auto_patch: |
320 | | - path = os.path.join(self.rv_dir, "monitors", path) |
321 | | - try: |
322 | | - os.mkdir(path) |
323 | | - except FileExistsError: |
324 | | - return |
325 | | - except: |
326 | | - print("Fail creating the output dir: %s" % self.name) |
327 | | - |
328 | | - def __write_file(self, file_name, content): |
329 | | - try: |
330 | | - file = open(file_name, 'w') |
331 | | - except: |
332 | | - print("Fail writing to file: %s" % file_name) |
333 | | - |
334 | | - file.write(content) |
335 | | - |
336 | | - file.close() |
337 | | - |
338 | | - def __create_file(self, file_name, content): |
339 | | - path = "%s/%s" % (self.name, file_name) |
340 | | - if self.auto_patch: |
341 | | - path = os.path.join(self.rv_dir, "monitors", path) |
342 | | - self.__write_file(path, content) |
343 | | - |
344 | | - def __get_main_name(self): |
345 | | - path = "%s/%s" % (self.name, "main.c") |
346 | | - if not os.path.exists(path): |
347 | | - return "main.c" |
348 | | - return "__main.c" |
349 | | - |
350 | | - def print_files(self): |
351 | | - main_c = self.fill_main_c() |
352 | | - |
353 | | - self.__create_directory() |
354 | | - |
355 | | - path = "%s.c" % self.name |
356 | | - self.__create_file(path, main_c) |
| 118 | + def fill_main_c(self): |
| 119 | + main_c = super().fill_main_c() |
357 | 120 |
|
358 | | - if self.container: |
359 | | - main_h = self.fill_main_container_h() |
360 | | - path = "%s.h" % self.name |
361 | | - self.__create_file(path, main_h) |
362 | | - else: |
363 | | - model_h = self.fill_model_h() |
364 | | - path = "%s.h" % self.name |
365 | | - self.__create_file(path, model_h) |
| 121 | + min_type = self.get_minimun_type() |
| 122 | + nr_events = len(self.events) |
| 123 | + monitor_type = self.fill_monitor_type() |
366 | 124 |
|
367 | | - trace_h = self.fill_trace_h() |
368 | | - path = "%s_trace.h" % self.name |
369 | | - self.__create_file(path, trace_h) |
| 125 | + main_c = main_c.replace("%%MIN_TYPE%%", min_type) |
| 126 | + main_c = main_c.replace("%%NR_EVENTS%%", str(nr_events)) |
| 127 | + main_c = main_c.replace("%%MONITOR_TYPE%%", monitor_type) |
370 | 128 |
|
371 | | - kconfig = self.fill_kconfig() |
372 | | - self.__create_file("Kconfig", kconfig) |
| 129 | + return main_c |
0 commit comments