tracing: Use defined fields and print_fmt to print formats
The calls ftrace_format_##call() and ftrace_define_fields_##call() are almost duplicate in functionality. With the addition of the print_fmt in previous patches, these two functions can be merged into one. The trace_define_field() defines the fields and links them into the struct ftrace_event_call. The previous patches introduced the print_fmt field and this can now be used with the trace_define_field() to create the event format file fields and print_fmt field. The struct ftrace_event_call->fields are used to print the fields The struct ftrace_event_call->print_fmt is used to print the "print fmt: XXXXXXXXXXX" line. Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> LKML-Reference: <4B273D49.5000006@cn.fujitsu.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
This commit is contained in:
parent
c7ef3a9004
commit
5a65e95622
1 changed files with 41 additions and 24 deletions
|
@ -528,33 +528,16 @@ extern char *__bad_type_size(void);
|
|||
#type, "common_" #name, offsetof(typeof(field), name), \
|
||||
sizeof(field.name), is_signed_type(type)
|
||||
|
||||
static int trace_write_header(struct trace_seq *s)
|
||||
{
|
||||
struct trace_entry field;
|
||||
|
||||
/* struct trace_entry */
|
||||
return trace_seq_printf(s,
|
||||
"\tfield:%s %s;\toffset:%zu;\tsize:%zu;\tsigned:%u;\n"
|
||||
"\tfield:%s %s;\toffset:%zu;\tsize:%zu;\tsigned:%u;\n"
|
||||
"\tfield:%s %s;\toffset:%zu;\tsize:%zu;\tsigned:%u;\n"
|
||||
"\tfield:%s %s;\toffset:%zu;\tsize:%zu;\tsigned:%u;\n"
|
||||
"\tfield:%s %s;\toffset:%zu;\tsize:%zu;\tsigned:%u;\n"
|
||||
"\n",
|
||||
FIELD(unsigned short, type),
|
||||
FIELD(unsigned char, flags),
|
||||
FIELD(unsigned char, preempt_count),
|
||||
FIELD(int, pid),
|
||||
FIELD(int, lock_depth));
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
event_format_read(struct file *filp, char __user *ubuf, size_t cnt,
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct ftrace_event_call *call = filp->private_data;
|
||||
struct ftrace_event_field *field;
|
||||
struct trace_seq *s;
|
||||
int common_field_count = 5;
|
||||
char *buf;
|
||||
int r;
|
||||
int r = 0;
|
||||
|
||||
if (*ppos)
|
||||
return 0;
|
||||
|
@ -565,14 +548,48 @@ event_format_read(struct file *filp, char __user *ubuf, size_t cnt,
|
|||
|
||||
trace_seq_init(s);
|
||||
|
||||
/* If any of the first writes fail, so will the show_format. */
|
||||
|
||||
trace_seq_printf(s, "name: %s\n", call->name);
|
||||
trace_seq_printf(s, "ID: %d\n", call->id);
|
||||
trace_seq_printf(s, "format:\n");
|
||||
trace_write_header(s);
|
||||
|
||||
r = call->show_format(call, s);
|
||||
list_for_each_entry_reverse(field, &call->fields, link) {
|
||||
/*
|
||||
* Smartly shows the array type(except dynamic array).
|
||||
* Normal:
|
||||
* field:TYPE VAR
|
||||
* If TYPE := TYPE[LEN], it is shown:
|
||||
* field:TYPE VAR[LEN]
|
||||
*/
|
||||
const char *array_descriptor = strchr(field->type, '[');
|
||||
|
||||
if (!strncmp(field->type, "__data_loc", 10))
|
||||
array_descriptor = NULL;
|
||||
|
||||
if (!array_descriptor) {
|
||||
r = trace_seq_printf(s, "\tfield:%s %s;\toffset:%u;"
|
||||
"\tsize:%u;\tsigned:%d;\n",
|
||||
field->type, field->name, field->offset,
|
||||
field->size, !!field->is_signed);
|
||||
} else {
|
||||
r = trace_seq_printf(s, "\tfield:%.*s %s%s;\toffset:%u;"
|
||||
"\tsize:%u;\tsigned:%d;\n",
|
||||
(int)(array_descriptor - field->type),
|
||||
field->type, field->name,
|
||||
array_descriptor, field->offset,
|
||||
field->size, !!field->is_signed);
|
||||
}
|
||||
|
||||
if (--common_field_count == 0)
|
||||
r = trace_seq_printf(s, "\n");
|
||||
|
||||
if (!r)
|
||||
break;
|
||||
}
|
||||
|
||||
if (r)
|
||||
r = trace_seq_printf(s, "\nprint fmt: %s\n",
|
||||
call->print_fmt);
|
||||
|
||||
if (!r) {
|
||||
/*
|
||||
* ug! The format output is bigger than a PAGE!!
|
||||
|
|
Loading…
Reference in a new issue