tracing/events: Add 'signed' field to format files
The sign info used for filters in the kernel is also useful to applications that process the trace stream. Add it to the format files and make it available to userspace. Signed-off-by: Tom Zanussi <tzanussi@gmail.com> Acked-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: rostedt@goodmis.org Cc: lizf@cn.fujitsu.com Cc: hch@infradead.org Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> LKML-Reference: <1254809398-8078-2-git-send-email-tzanussi@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
parent
d9b2002c40
commit
26a50744b2
|
@ -120,9 +120,10 @@
|
||||||
#undef __field
|
#undef __field
|
||||||
#define __field(type, item) \
|
#define __field(type, item) \
|
||||||
ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \
|
ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \
|
||||||
"offset:%u;\tsize:%u;\n", \
|
"offset:%u;\tsize:%u;\tsigned:%u;\n", \
|
||||||
(unsigned int)offsetof(typeof(field), item), \
|
(unsigned int)offsetof(typeof(field), item), \
|
||||||
(unsigned int)sizeof(field.item)); \
|
(unsigned int)sizeof(field.item), \
|
||||||
|
(unsigned int)is_signed_type(type)); \
|
||||||
if (!ret) \
|
if (!ret) \
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -132,19 +133,21 @@
|
||||||
#undef __array
|
#undef __array
|
||||||
#define __array(type, item, len) \
|
#define __array(type, item, len) \
|
||||||
ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \
|
ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \
|
||||||
"offset:%u;\tsize:%u;\n", \
|
"offset:%u;\tsize:%u;\tsigned:%u;\n", \
|
||||||
(unsigned int)offsetof(typeof(field), item), \
|
(unsigned int)offsetof(typeof(field), item), \
|
||||||
(unsigned int)sizeof(field.item)); \
|
(unsigned int)sizeof(field.item), \
|
||||||
|
(unsigned int)is_signed_type(type)); \
|
||||||
if (!ret) \
|
if (!ret) \
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#undef __dynamic_array
|
#undef __dynamic_array
|
||||||
#define __dynamic_array(type, item, len) \
|
#define __dynamic_array(type, item, len) \
|
||||||
ret = trace_seq_printf(s, "\tfield:__data_loc " #type "[] " #item ";\t"\
|
ret = trace_seq_printf(s, "\tfield:__data_loc " #type "[] " #item ";\t"\
|
||||||
"offset:%u;\tsize:%u;\n", \
|
"offset:%u;\tsize:%u;\tsigned:%u;\n", \
|
||||||
(unsigned int)offsetof(typeof(field), \
|
(unsigned int)offsetof(typeof(field), \
|
||||||
__data_loc_##item), \
|
__data_loc_##item), \
|
||||||
(unsigned int)sizeof(field.__data_loc_##item)); \
|
(unsigned int)sizeof(field.__data_loc_##item), \
|
||||||
|
(unsigned int)is_signed_type(type)); \
|
||||||
if (!ret) \
|
if (!ret) \
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -397,18 +397,21 @@ int ring_buffer_print_page_header(struct trace_seq *s)
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = trace_seq_printf(s, "\tfield: u64 timestamp;\t"
|
ret = trace_seq_printf(s, "\tfield: u64 timestamp;\t"
|
||||||
"offset:0;\tsize:%u;\n",
|
"offset:0;\tsize:%u;\tsigned:%u;\n",
|
||||||
(unsigned int)sizeof(field.time_stamp));
|
(unsigned int)sizeof(field.time_stamp),
|
||||||
|
(unsigned int)is_signed_type(u64));
|
||||||
|
|
||||||
ret = trace_seq_printf(s, "\tfield: local_t commit;\t"
|
ret = trace_seq_printf(s, "\tfield: local_t commit;\t"
|
||||||
"offset:%u;\tsize:%u;\n",
|
"offset:%u;\tsize:%u;\tsigned:%u;\n",
|
||||||
(unsigned int)offsetof(typeof(field), commit),
|
(unsigned int)offsetof(typeof(field), commit),
|
||||||
(unsigned int)sizeof(field.commit));
|
(unsigned int)sizeof(field.commit),
|
||||||
|
(unsigned int)is_signed_type(long));
|
||||||
|
|
||||||
ret = trace_seq_printf(s, "\tfield: char data;\t"
|
ret = trace_seq_printf(s, "\tfield: char data;\t"
|
||||||
"offset:%u;\tsize:%u;\n",
|
"offset:%u;\tsize:%u;\tsigned:%u;\n",
|
||||||
(unsigned int)offsetof(typeof(field), data),
|
(unsigned int)offsetof(typeof(field), data),
|
||||||
(unsigned int)BUF_PAGE_SIZE);
|
(unsigned int)BUF_PAGE_SIZE,
|
||||||
|
(unsigned int)is_signed_type(char));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -507,7 +507,7 @@ extern char *__bad_type_size(void);
|
||||||
#define FIELD(type, name) \
|
#define FIELD(type, name) \
|
||||||
sizeof(type) != sizeof(field.name) ? __bad_type_size() : \
|
sizeof(type) != sizeof(field.name) ? __bad_type_size() : \
|
||||||
#type, "common_" #name, offsetof(typeof(field), name), \
|
#type, "common_" #name, offsetof(typeof(field), name), \
|
||||||
sizeof(field.name)
|
sizeof(field.name), is_signed_type(type)
|
||||||
|
|
||||||
static int trace_write_header(struct trace_seq *s)
|
static int trace_write_header(struct trace_seq *s)
|
||||||
{
|
{
|
||||||
|
@ -515,17 +515,17 @@ static int trace_write_header(struct trace_seq *s)
|
||||||
|
|
||||||
/* struct trace_entry */
|
/* struct trace_entry */
|
||||||
return trace_seq_printf(s,
|
return trace_seq_printf(s,
|
||||||
"\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
|
"\tfield:%s %s;\toffset:%zu;\tsize:%zu;\tsigned:%u;\n"
|
||||||
"\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
|
"\tfield:%s %s;\toffset:%zu;\tsize:%zu;\tsigned:%u;\n"
|
||||||
"\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
|
"\tfield:%s %s;\toffset:%zu;\tsize:%zu;\tsigned:%u;\n"
|
||||||
"\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
|
"\tfield:%s %s;\toffset:%zu;\tsize:%zu;\tsigned:%u;\n"
|
||||||
"\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
|
"\tfield:%s %s;\toffset:%zu;\tsize:%zu;\tsigned:%u;\n"
|
||||||
"\n",
|
"\n",
|
||||||
FIELD(unsigned short, type),
|
FIELD(unsigned short, type),
|
||||||
FIELD(unsigned char, flags),
|
FIELD(unsigned char, flags),
|
||||||
FIELD(unsigned char, preempt_count),
|
FIELD(unsigned char, preempt_count),
|
||||||
FIELD(int, pid),
|
FIELD(int, pid),
|
||||||
FIELD(int, lock_depth));
|
FIELD(int, lock_depth));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
|
|
|
@ -66,44 +66,47 @@ static void __used ____ftrace_check_##name(void) \
|
||||||
#undef __field
|
#undef __field
|
||||||
#define __field(type, item) \
|
#define __field(type, item) \
|
||||||
ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \
|
ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \
|
||||||
"offset:%zu;\tsize:%zu;\n", \
|
"offset:%zu;\tsize:%zu;\tsigned:%u;\n", \
|
||||||
offsetof(typeof(field), item), \
|
offsetof(typeof(field), item), \
|
||||||
sizeof(field.item)); \
|
sizeof(field.item), is_signed_type(type)); \
|
||||||
if (!ret) \
|
if (!ret) \
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#undef __field_desc
|
#undef __field_desc
|
||||||
#define __field_desc(type, container, item) \
|
#define __field_desc(type, container, item) \
|
||||||
ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \
|
ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \
|
||||||
"offset:%zu;\tsize:%zu;\n", \
|
"offset:%zu;\tsize:%zu;\tsigned:%u;\n", \
|
||||||
offsetof(typeof(field), container.item), \
|
offsetof(typeof(field), container.item), \
|
||||||
sizeof(field.container.item)); \
|
sizeof(field.container.item), \
|
||||||
|
is_signed_type(type)); \
|
||||||
if (!ret) \
|
if (!ret) \
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#undef __array
|
#undef __array
|
||||||
#define __array(type, item, len) \
|
#define __array(type, item, len) \
|
||||||
ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \
|
ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \
|
||||||
"offset:%zu;\tsize:%zu;\n", \
|
"offset:%zu;\tsize:%zu;\tsigned:%u;\n", \
|
||||||
offsetof(typeof(field), item), \
|
offsetof(typeof(field), item), \
|
||||||
sizeof(field.item)); \
|
sizeof(field.item), is_signed_type(type)); \
|
||||||
if (!ret) \
|
if (!ret) \
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#undef __array_desc
|
#undef __array_desc
|
||||||
#define __array_desc(type, container, item, len) \
|
#define __array_desc(type, container, item, len) \
|
||||||
ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \
|
ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \
|
||||||
"offset:%zu;\tsize:%zu;\n", \
|
"offset:%zu;\tsize:%zu;\tsigned:%u;\n", \
|
||||||
offsetof(typeof(field), container.item), \
|
offsetof(typeof(field), container.item), \
|
||||||
sizeof(field.container.item)); \
|
sizeof(field.container.item), \
|
||||||
|
is_signed_type(type)); \
|
||||||
if (!ret) \
|
if (!ret) \
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#undef __dynamic_array
|
#undef __dynamic_array
|
||||||
#define __dynamic_array(type, item) \
|
#define __dynamic_array(type, item) \
|
||||||
ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \
|
ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \
|
||||||
"offset:%zu;\tsize:0;\n", \
|
"offset:%zu;\tsize:0;\tsigned:%u;\n", \
|
||||||
offsetof(typeof(field), item)); \
|
offsetof(typeof(field), item), \
|
||||||
|
is_signed_type(type)); \
|
||||||
if (!ret) \
|
if (!ret) \
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,8 @@ extern char *__bad_type_size(void);
|
||||||
#define SYSCALL_FIELD(type, name) \
|
#define SYSCALL_FIELD(type, name) \
|
||||||
sizeof(type) != sizeof(trace.name) ? \
|
sizeof(type) != sizeof(trace.name) ? \
|
||||||
__bad_type_size() : \
|
__bad_type_size() : \
|
||||||
#type, #name, offsetof(typeof(trace), name), sizeof(trace.name)
|
#type, #name, offsetof(typeof(trace), name), \
|
||||||
|
sizeof(trace.name), is_signed_type(type)
|
||||||
|
|
||||||
int syscall_enter_format(struct ftrace_event_call *call, struct trace_seq *s)
|
int syscall_enter_format(struct ftrace_event_call *call, struct trace_seq *s)
|
||||||
{
|
{
|
||||||
|
@ -120,7 +121,8 @@ int syscall_enter_format(struct ftrace_event_call *call, struct trace_seq *s)
|
||||||
if (!entry)
|
if (!entry)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ret = trace_seq_printf(s, "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n",
|
ret = trace_seq_printf(s, "\tfield:%s %s;\toffset:%zu;\tsize:%zu;"
|
||||||
|
"\tsigned:%u;\n",
|
||||||
SYSCALL_FIELD(int, nr));
|
SYSCALL_FIELD(int, nr));
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -130,8 +132,10 @@ int syscall_enter_format(struct ftrace_event_call *call, struct trace_seq *s)
|
||||||
entry->args[i]);
|
entry->args[i]);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return 0;
|
return 0;
|
||||||
ret = trace_seq_printf(s, "\toffset:%d;\tsize:%zu;\n", offset,
|
ret = trace_seq_printf(s, "\toffset:%d;\tsize:%zu;"
|
||||||
sizeof(unsigned long));
|
"\tsigned:%u;\n", offset,
|
||||||
|
sizeof(unsigned long),
|
||||||
|
is_signed_type(unsigned long));
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return 0;
|
return 0;
|
||||||
offset += sizeof(unsigned long);
|
offset += sizeof(unsigned long);
|
||||||
|
@ -163,8 +167,10 @@ int syscall_exit_format(struct ftrace_event_call *call, struct trace_seq *s)
|
||||||
struct syscall_trace_exit trace;
|
struct syscall_trace_exit trace;
|
||||||
|
|
||||||
ret = trace_seq_printf(s,
|
ret = trace_seq_printf(s,
|
||||||
"\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
|
"\tfield:%s %s;\toffset:%zu;\tsize:%zu;"
|
||||||
"\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n",
|
"\tsigned:%u;\n"
|
||||||
|
"\tfield:%s %s;\toffset:%zu;\tsize:%zu;"
|
||||||
|
"\tsigned:%u;\n",
|
||||||
SYSCALL_FIELD(int, nr),
|
SYSCALL_FIELD(int, nr),
|
||||||
SYSCALL_FIELD(long, ret));
|
SYSCALL_FIELD(long, ret));
|
||||||
if (!ret)
|
if (!ret)
|
||||||
|
@ -212,7 +218,7 @@ int syscall_exit_define_fields(struct ftrace_event_call *call)
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = trace_define_field(call, SYSCALL_FIELD(long, ret), 0,
|
ret = trace_define_field(call, SYSCALL_FIELD(long, ret),
|
||||||
FILTER_OTHER);
|
FILTER_OTHER);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -894,6 +894,21 @@ static int event_read_fields(struct event *event, struct format_field **fields)
|
||||||
field->size = strtoul(token, NULL, 0);
|
field->size = strtoul(token, NULL, 0);
|
||||||
free_token(token);
|
free_token(token);
|
||||||
|
|
||||||
|
if (read_expected(EVENT_OP, (char *)";") < 0)
|
||||||
|
goto fail_expect;
|
||||||
|
|
||||||
|
if (read_expected(EVENT_ITEM, (char *)"signed") < 0)
|
||||||
|
goto fail_expect;
|
||||||
|
|
||||||
|
if (read_expected(EVENT_OP, (char *)":") < 0)
|
||||||
|
goto fail_expect;
|
||||||
|
|
||||||
|
if (read_expect_type(EVENT_ITEM, &token))
|
||||||
|
goto fail;
|
||||||
|
if (strtoul(token, NULL, 0))
|
||||||
|
field->flags |= FIELD_IS_SIGNED;
|
||||||
|
free_token(token);
|
||||||
|
|
||||||
if (read_expected(EVENT_OP, (char *)";") < 0)
|
if (read_expected(EVENT_OP, (char *)";") < 0)
|
||||||
goto fail_expect;
|
goto fail_expect;
|
||||||
|
|
||||||
|
@ -2843,6 +2858,15 @@ static void parse_header_field(char *type,
|
||||||
return;
|
return;
|
||||||
*size = atoi(token);
|
*size = atoi(token);
|
||||||
free_token(token);
|
free_token(token);
|
||||||
|
if (read_expected(EVENT_OP, (char *)";") < 0)
|
||||||
|
return;
|
||||||
|
if (read_expected(EVENT_ITEM, (char *)"signed") < 0)
|
||||||
|
return;
|
||||||
|
if (read_expected(EVENT_OP, (char *)":") < 0)
|
||||||
|
return;
|
||||||
|
if (read_expect_type(EVENT_ITEM, &token) < 0)
|
||||||
|
return;
|
||||||
|
free_token(token);
|
||||||
if (read_expected(EVENT_OP, (char *)";") < 0)
|
if (read_expected(EVENT_OP, (char *)";") < 0)
|
||||||
return;
|
return;
|
||||||
if (read_expect_type(EVENT_NEWLINE, &token) < 0)
|
if (read_expect_type(EVENT_NEWLINE, &token) < 0)
|
||||||
|
|
|
@ -26,6 +26,7 @@ enum {
|
||||||
enum format_flags {
|
enum format_flags {
|
||||||
FIELD_IS_ARRAY = 1,
|
FIELD_IS_ARRAY = 1,
|
||||||
FIELD_IS_POINTER = 2,
|
FIELD_IS_POINTER = 2,
|
||||||
|
FIELD_IS_SIGNED = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct format_field {
|
struct format_field {
|
||||||
|
|
Loading…
Reference in New Issue