1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2009, Steven Rostedt <srostedt@redhat.com>
11 #include "trace-event.h"
13 #include <linux/ctype.h>
14 #include <linux/kernel.h>
15 #include <event-parse.h>
17 static int get_common_field(struct scripting_context
*context
,
18 int *offset
, int *size
, const char *type
)
20 struct tep_handle
*pevent
= context
->pevent
;
21 struct tep_event
*event
;
22 struct tep_format_field
*field
;
26 event
= tep_get_first_event(pevent
);
30 field
= tep_find_common_field(event
, type
);
33 *offset
= field
->offset
;
37 return tep_read_number(pevent
, context
->event_data
+ *offset
, *size
);
40 int common_lock_depth(struct scripting_context
*context
)
46 ret
= get_common_field(context
, &size
, &offset
,
54 int common_flags(struct scripting_context
*context
)
60 ret
= get_common_field(context
, &size
, &offset
,
68 int common_pc(struct scripting_context
*context
)
74 ret
= get_common_field(context
, &size
, &offset
,
75 "common_preempt_count");
83 raw_field_value(struct tep_event
*event
, const char *name
, void *data
)
85 struct tep_format_field
*field
;
86 unsigned long long val
;
88 field
= tep_find_any_field(event
, name
);
92 tep_read_number_field(field
, data
, &val
);
97 unsigned long long read_size(struct tep_event
*event
, void *ptr
, int size
)
99 return tep_read_number(event
->tep
, ptr
, size
);
102 void event_format__fprintf(struct tep_event
*event
,
103 int cpu
, void *data
, int size
, FILE *fp
)
105 struct tep_record record
;
108 memset(&record
, 0, sizeof(record
));
114 tep_print_event(event
->tep
, &s
, &record
, "%s", TEP_PRINT_INFO
);
115 trace_seq_do_fprintf(&s
, fp
);
116 trace_seq_destroy(&s
);
120 * prev_state is of size long, which is 32 bits on 32 bit architectures.
121 * As it needs to have the same bits for both 32 bit and 64 bit architectures
122 * we can just assume that the flags we care about will all be within
125 #define MAX_STATE_BITS 32
127 static const char *convert_sym(struct tep_print_flag_sym
*sym
)
129 static char save_states
[MAX_STATE_BITS
+ 1];
131 memset(save_states
, 0, sizeof(save_states
));
133 /* This is the flags for the prev_state_field, now make them into a string */
134 for (; sym
; sym
= sym
->next
) {
135 long bitmask
= strtoul(sym
->value
, NULL
, 0);
138 for (i
= 0; !(bitmask
& 1); i
++)
141 if (i
>= MAX_STATE_BITS
)
144 save_states
[i
] = sym
->str
[0];
150 static struct tep_print_arg_field
*
151 find_arg_field(struct tep_format_field
*prev_state_field
, struct tep_print_arg
*arg
)
153 struct tep_print_arg_field
*field
;
158 if (arg
->type
== TEP_PRINT_FIELD
)
161 if (arg
->type
== TEP_PRINT_OP
) {
162 field
= find_arg_field(prev_state_field
, arg
->op
.left
);
163 if (field
&& field
->field
== prev_state_field
)
165 field
= find_arg_field(prev_state_field
, arg
->op
.right
);
166 if (field
&& field
->field
== prev_state_field
)
172 static struct tep_print_flag_sym
*
173 test_flags(struct tep_format_field
*prev_state_field
, struct tep_print_arg
*arg
)
175 struct tep_print_arg_field
*field
;
177 field
= find_arg_field(prev_state_field
, arg
->flags
.field
);
181 return arg
->flags
.flags
;
184 static struct tep_print_flag_sym
*
185 search_op(struct tep_format_field
*prev_state_field
, struct tep_print_arg
*arg
)
187 struct tep_print_flag_sym
*sym
= NULL
;
192 if (arg
->type
== TEP_PRINT_OP
) {
193 sym
= search_op(prev_state_field
, arg
->op
.left
);
197 sym
= search_op(prev_state_field
, arg
->op
.right
);
200 } else if (arg
->type
== TEP_PRINT_FLAGS
) {
201 sym
= test_flags(prev_state_field
, arg
);
207 const char *parse_task_states(struct tep_format_field
*state_field
)
209 struct tep_print_flag_sym
*sym
;
210 struct tep_print_arg
*arg
;
211 struct tep_event
*event
;
213 event
= state_field
->event
;
216 * Look at the event format fields, and search for where
217 * the prev_state is parsed via the format flags.
219 for (arg
= event
->print_fmt
.args
; arg
; arg
= arg
->next
) {
221 * Currently, the __print_flags() for the prev_state
222 * is embedded in operations, so they too must be
225 sym
= search_op(state_field
, arg
);
227 return convert_sym(sym
);
232 void parse_ftrace_printk(struct tep_handle
*pevent
,
233 char *file
, unsigned int size __maybe_unused
)
235 unsigned long long addr
;
242 line
= strtok_r(file
, "\n", &next
);
244 addr_str
= strtok_r(line
, ":", &fmt
);
246 pr_warning("printk format with empty entry");
249 addr
= strtoull(addr_str
, NULL
, 16);
250 /* fmt still has a space, skip it */
251 printk
= strdup(fmt
+1);
252 line
= strtok_r(NULL
, "\n", &next
);
253 tep_register_print_string(pevent
, printk
, addr
);
258 void parse_saved_cmdline(struct tep_handle
*pevent
,
259 char *file
, unsigned int size __maybe_unused
)
261 char comm
[17]; /* Max comm length in the kernel is 16. */
266 line
= strtok_r(file
, "\n", &next
);
268 if (sscanf(line
, "%d %16s", &pid
, comm
) == 2)
269 tep_register_comm(pevent
, comm
, pid
);
270 line
= strtok_r(NULL
, "\n", &next
);
274 int parse_ftrace_file(struct tep_handle
*pevent
, char *buf
, unsigned long size
)
276 return tep_parse_event(pevent
, buf
, size
, "ftrace");
279 int parse_event_file(struct tep_handle
*pevent
,
280 char *buf
, unsigned long size
, char *sys
)
282 return tep_parse_event(pevent
, buf
, size
, sys
);
287 unsigned long long value
;
290 static const struct flag flags
[] = {
292 { "TIMER_SOFTIRQ", 1 },
293 { "NET_TX_SOFTIRQ", 2 },
294 { "NET_RX_SOFTIRQ", 3 },
295 { "BLOCK_SOFTIRQ", 4 },
296 { "IRQ_POLL_SOFTIRQ", 5 },
297 { "TASKLET_SOFTIRQ", 6 },
298 { "SCHED_SOFTIRQ", 7 },
299 { "HRTIMER_SOFTIRQ", 8 },
300 { "RCU_SOFTIRQ", 9 },
302 { "HRTIMER_NORESTART", 0 },
303 { "HRTIMER_RESTART", 1 },
306 unsigned long long eval_flag(const char *flag
)
311 * Some flags in the format files do not get converted.
312 * If the flag is not numeric, see if it is something that
313 * we already know about.
315 if (isdigit(flag
[0]))
316 return strtoull(flag
, NULL
, 0);
318 for (i
= 0; i
< (int)(ARRAY_SIZE(flags
)); i
++)
319 if (strcmp(flags
[i
].name
, flag
) == 0)
320 return flags
[i
].value
;