Add explicit vmalloc_sync_all
[lttng-modules.git] / probes / lttng-types.c
1 /*
2 * probes/lttng-types.c
3 *
4 * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 *
6 * LTTng types.
7 */
8
9 #include <linux/module.h>
10 #include <linux/types.h>
11 #include <linux/seq_file.h>
12 #include <linux/jbd.h> /* tid_t */
13 #include <linux/debugfs.h>
14 #include <linux/vmalloc.h> /* for vmalloc_sync_all */
15 #include "lttng-types.h"
16
17 struct dentry *lttng_types_dentry;
18
19 #undef ENTRY
20 #define ENTRY(name) [atype_##name] = #name
21
22 const char * const astract_types[NR_ABSTRACT_TYPES] = {
23 ENTRY(integer),
24 ENTRY(enum),
25 ENTRY(array),
26 ENTRY(sequence),
27 ENTRY(string),
28 };
29
30 #undef ENTRY
31 #define ENTRY(name) [lttng_encode_##name] = #name
32
33 const char * const string_encodings[NR_STRING_ENCODINGS] = {
34 ENTRY(UTF8),
35 ENTRY(ASCII),
36 };
37
38 #define STAGE_EXPORT_ENUMS
39 #include "lttng-types.h"
40 #include "lttng-type-list.h"
41 #undef STAGE_EXPORT_ENUMS
42
43 struct lttng_type lttng_types[] = {
44 #define STAGE_EXPORT_TYPES
45 #include "lttng-types.h"
46 #include "lttng-type-list.h"
47 #undef STAGE_EXPORT_TYPES
48 };
49
50 static void print_indent(struct seq_file *m, unsigned int indent)
51 {
52 int i;
53
54 for (i = 0; i < indent; i++)
55 seq_printf(m, "\t");
56 }
57
58 static void print_enum(struct seq_file *m, unsigned int indent,
59 const struct lttng_enum *lttng_enum)
60 {
61 int i;
62
63 for (i = 0; i < lttng_enum->len; i++) {
64 print_indent(m, indent);
65 if (lttng_enum->entries[i].start == lttng_enum->entries[i].end)
66 seq_printf(m, "{ %llu, %s },\n",
67 lttng_enum->entries[i].start,
68 lttng_enum->entries[i].string);
69 else
70 seq_printf(m, "{ { %llu, %llu }, %s },\n",
71 lttng_enum->entries[i].start,
72 lttng_enum->entries[i].end,
73 lttng_enum->entries[i].string);
74 }
75 }
76
77 void lttng_print_event_type(struct seq_file *m, unsigned int indent,
78 const struct lttng_type *type)
79 {
80 print_indent(m, indent);
81 switch(type->atype) {
82 case atype_integer:
83 seq_printf(m, "type %s%s{ parent = %s; size = %u; signed = %u; align = %u;",
84 type->name ? : "", type->name ? " " : "",
85 astract_types[type->atype],
86 type->u.integer.size,
87 type->u.integer.signedness,
88 type->u.integer.alignment);
89 if (type->u.integer.reverse_byte_order)
90 seq_printf(m, " byte_order = %s;",
91 (__BYTE_ORDER == __LITTLE_ENDIAN) ?
92 "be" : "le");
93 seq_printf(m, " }");
94 break;
95 case atype_enum:
96 seq_printf(m, "type %s%s{ parent = %s; parent.parent = %s; map = {\n",
97 type->name ? : "", type->name ? " " : "",
98 astract_types[type->atype],
99 type->u.enumeration.parent_type);
100 print_enum(m, indent + 2, &type->u.enumeration.def);
101 print_indent(m, indent + 1);
102 seq_printf(m, "};\n");
103 print_indent(m, indent);
104 seq_printf(m, "}");
105 break;
106 case atype_array:
107 seq_printf(m, "type %s%s{ parent = %s; elem_type = %s; length = %u; }",
108 type->name ? : "", type->name ? " " : "",
109 astract_types[type->atype],
110 type->u.array.elem_type,
111 type->u.array.length);
112 break;
113 case atype_sequence:
114 seq_printf(m, "type %s%s{ parent = %s; elem_type = %s; length_type = %s; }",
115 type->name ? : "", type->name ? " " : "",
116 astract_types[type->atype],
117 type->u.sequence.elem_type,
118 type->u.sequence.length_type);
119 break;
120 case atype_string:
121 seq_printf(m, "type %s%s{ parent = %s; encoding = %s; }",
122 type->name ? : "", type->name ? " " : "",
123 astract_types[type->atype],
124 string_encodings[type->u.string.encoding]);
125 break;
126 default:
127 seq_printf(m, "<<< unknown abstract type %s for type %s%s>>>",
128 astract_types[type->atype],
129 type->name ? : "", type->name ? " " : "");
130 }
131 }
132 EXPORT_SYMBOL_GPL(lttng_print_event_type);
133
134 static void *lttng_seq_start(struct seq_file *m, loff_t *pos)
135 {
136 struct lttng_type *type = &lttng_types[*pos];
137
138 if (type > &lttng_types[ARRAY_SIZE(lttng_types) - 1])
139 return NULL;
140 return type;
141 }
142
143 static void *lttng_seq_next(struct seq_file *m, void *v, loff_t *ppos)
144 {
145 struct lttng_type *type = &lttng_types[++(*ppos)];
146
147 if (type > &lttng_types[ARRAY_SIZE(lttng_types) - 1])
148 return NULL;
149 return type;
150 }
151
152 static void lttng_seq_stop(struct seq_file *m, void *v)
153 {
154 }
155
156 static int lttng_seq_show(struct seq_file *m, void *v)
157 {
158 struct lttng_type *type = v;
159
160 lttng_print_event_type(m, 0, type);
161 seq_printf(m, ";\n");
162 return 0;
163 }
164
165 static const struct seq_operations lttng_types_seq_ops = {
166 .start = lttng_seq_start,
167 .next = lttng_seq_next,
168 .stop = lttng_seq_stop,
169 .show = lttng_seq_show,
170 };
171
172 static int
173 lttng_types_open(struct inode *inode, struct file *file)
174 {
175 return seq_open(file, &lttng_types_seq_ops);
176 }
177
178 static const struct file_operations lttng_types_fops = {
179 .open = lttng_types_open,
180 .read = seq_read,
181 .llseek = seq_lseek,
182 .release = seq_release_private,
183 };
184
185 static int lttng_types_init(void)
186 {
187 int ret = 0;
188
189 vmalloc_sync_all();
190 lttng_types_dentry = debugfs_create_file("lttng-types", S_IWUSR,
191 NULL, NULL, &lttng_types_fops);
192 if (IS_ERR(lttng_types_dentry) || !lttng_types_dentry) {
193 printk(KERN_ERR "Error creating LTTng type export file\n");
194 ret = -ENOMEM;
195 goto error;
196 }
197 error:
198 return ret;
199 }
200
201 module_init(lttng_types_init);
202
203 static void lttng_types_exit(void)
204 {
205 debugfs_remove(lttng_types_dentry);
206 }
207
208 module_exit(lttng_types_exit);
209
210 MODULE_LICENSE("GPL and additional rights");
211 MODULE_AUTHOR("Mathieu Desnoyers <mathieu.desnoyers@efficios.com>");
212 MODULE_DESCRIPTION("LTTng types");
This page took 0.032744 seconds and 4 git commands to generate.