mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-04 04:06:26 +00:00
perf evsel: Rename get_states() to parse_task_states() and make it public
Since get_states() assumes the existence of libtraceevent, so move to where it should belong, i.e, util/trace-event-parse.c, and also rename it to parse_task_states(). Leave evsel_getstate() untouched as it fits well in the evsel category. Also make some necessary tweaks for python support, and get it verified with: perf test python. Signed-off-by: Ze Gao <zegao@tencent.com> Cc: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Namhyung Kim <namhyung@kernel.org> Link: https://lore.kernel.org/r/20240123070210.1669843-2-zegao@tencent.com
This commit is contained in:
parent
7727d59de4
commit
20018398fc
@ -370,7 +370,7 @@ python-clean := $(call QUIET_CLEAN, python) $(RM) -r $(PYTHON_EXTBUILD) $(OUTPUT
|
||||
ifeq ($(CONFIG_LIBTRACEEVENT),y)
|
||||
PYTHON_EXT_SRCS := $(shell grep -v ^\# util/python-ext-sources)
|
||||
else
|
||||
PYTHON_EXT_SRCS := $(shell grep -v ^\#\\\|util/trace-event.c util/python-ext-sources)
|
||||
PYTHON_EXT_SRCS := $(shell grep -v ^\#\\\|util/trace-event.c\\\|util/trace-event-parse.c util/python-ext-sources)
|
||||
endif
|
||||
|
||||
PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBAPI)
|
||||
|
@ -2851,119 +2851,6 @@ u64 evsel__intval_common(struct evsel *evsel, struct perf_sample *sample, const
|
||||
return field ? format_field__intval(field, sample, evsel->needs_swap) : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* prev_state is of size long, which is 32 bits on 32 bit architectures.
|
||||
* As it needs to have the same bits for both 32 bit and 64 bit architectures
|
||||
* we can just assume that the flags we care about will all be within
|
||||
* the 32 bits.
|
||||
*/
|
||||
#define MAX_STATE_BITS 32
|
||||
|
||||
static const char *convert_sym(struct tep_print_flag_sym *sym)
|
||||
{
|
||||
static char save_states[MAX_STATE_BITS + 1];
|
||||
|
||||
memset(save_states, 0, sizeof(save_states));
|
||||
|
||||
/* This is the flags for the prev_state_field, now make them into a string */
|
||||
for (; sym; sym = sym->next) {
|
||||
long bitmask = strtoul(sym->value, NULL, 0);
|
||||
int i;
|
||||
|
||||
for (i = 0; !(bitmask & 1); i++)
|
||||
bitmask >>= 1;
|
||||
|
||||
if (i >= MAX_STATE_BITS)
|
||||
continue;
|
||||
|
||||
save_states[i] = sym->str[0];
|
||||
}
|
||||
|
||||
return save_states;
|
||||
}
|
||||
|
||||
static struct tep_print_arg_field *
|
||||
find_arg_field(struct tep_format_field *prev_state_field, struct tep_print_arg *arg)
|
||||
{
|
||||
struct tep_print_arg_field *field;
|
||||
|
||||
if (!arg)
|
||||
return NULL;
|
||||
|
||||
if (arg->type == TEP_PRINT_FIELD)
|
||||
return &arg->field;
|
||||
|
||||
if (arg->type == TEP_PRINT_OP) {
|
||||
field = find_arg_field(prev_state_field, arg->op.left);
|
||||
if (field && field->field == prev_state_field)
|
||||
return field;
|
||||
field = find_arg_field(prev_state_field, arg->op.right);
|
||||
if (field && field->field == prev_state_field)
|
||||
return field;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct tep_print_flag_sym *
|
||||
test_flags(struct tep_format_field *prev_state_field, struct tep_print_arg *arg)
|
||||
{
|
||||
struct tep_print_arg_field *field;
|
||||
|
||||
field = find_arg_field(prev_state_field, arg->flags.field);
|
||||
if (!field)
|
||||
return NULL;
|
||||
|
||||
return arg->flags.flags;
|
||||
}
|
||||
|
||||
static struct tep_print_flag_sym *
|
||||
search_op(struct tep_format_field *prev_state_field, struct tep_print_arg *arg)
|
||||
{
|
||||
struct tep_print_flag_sym *sym = NULL;
|
||||
|
||||
if (!arg)
|
||||
return NULL;
|
||||
|
||||
if (arg->type == TEP_PRINT_OP) {
|
||||
sym = search_op(prev_state_field, arg->op.left);
|
||||
if (sym)
|
||||
return sym;
|
||||
|
||||
sym = search_op(prev_state_field, arg->op.right);
|
||||
if (sym)
|
||||
return sym;
|
||||
} else if (arg->type == TEP_PRINT_FLAGS) {
|
||||
sym = test_flags(prev_state_field, arg);
|
||||
}
|
||||
|
||||
return sym;
|
||||
}
|
||||
|
||||
static const char *get_states(struct tep_format_field *prev_state_field)
|
||||
{
|
||||
struct tep_print_flag_sym *sym;
|
||||
struct tep_print_arg *arg;
|
||||
struct tep_event *event;
|
||||
|
||||
event = prev_state_field->event;
|
||||
|
||||
/*
|
||||
* Look at the event format fields, and search for where
|
||||
* the prev_state is parsed via the format flags.
|
||||
*/
|
||||
for (arg = event->print_fmt.args; arg; arg = arg->next) {
|
||||
/*
|
||||
* Currently, the __print_flags() for the prev_state
|
||||
* is embedded in operations, so they too must be
|
||||
* searched.
|
||||
*/
|
||||
sym = search_op(prev_state_field, arg);
|
||||
if (sym)
|
||||
return convert_sym(sym);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char evsel__taskstate(struct evsel *evsel, struct perf_sample *sample, const char *name)
|
||||
{
|
||||
static struct tep_format_field *prev_state_field;
|
||||
@ -2979,7 +2866,7 @@ char evsel__taskstate(struct evsel *evsel, struct perf_sample *sample, const cha
|
||||
return state;
|
||||
|
||||
if (!states || field != prev_state_field) {
|
||||
states = get_states(field);
|
||||
states = parse_task_states(field);
|
||||
if (!states)
|
||||
return state;
|
||||
prev_state_field = field;
|
||||
|
@ -31,6 +31,7 @@ util/counts.c
|
||||
util/print_binary.c
|
||||
util/strlist.c
|
||||
util/trace-event.c
|
||||
util/trace-event-parse.c
|
||||
../lib/rbtree.c
|
||||
util/string.c
|
||||
util/symbol_fprintf.c
|
||||
|
@ -85,6 +85,7 @@ if '-DHAVE_LIBTRACEEVENT' in cflags:
|
||||
extra_libraries += [ 'traceevent' ]
|
||||
else:
|
||||
ext_sources.remove('util/trace-event.c')
|
||||
ext_sources.remove('util/trace-event-parse.c')
|
||||
|
||||
# use full paths with source files
|
||||
ext_sources = list(map(lambda x: '%s/%s' % (src_perf, x) , ext_sources))
|
||||
|
@ -122,6 +122,119 @@ void event_format__print(struct tep_event *event,
|
||||
return event_format__fprintf(event, cpu, data, size, stdout);
|
||||
}
|
||||
|
||||
/*
|
||||
* prev_state is of size long, which is 32 bits on 32 bit architectures.
|
||||
* As it needs to have the same bits for both 32 bit and 64 bit architectures
|
||||
* we can just assume that the flags we care about will all be within
|
||||
* the 32 bits.
|
||||
*/
|
||||
#define MAX_STATE_BITS 32
|
||||
|
||||
static const char *convert_sym(struct tep_print_flag_sym *sym)
|
||||
{
|
||||
static char save_states[MAX_STATE_BITS + 1];
|
||||
|
||||
memset(save_states, 0, sizeof(save_states));
|
||||
|
||||
/* This is the flags for the prev_state_field, now make them into a string */
|
||||
for (; sym; sym = sym->next) {
|
||||
long bitmask = strtoul(sym->value, NULL, 0);
|
||||
int i;
|
||||
|
||||
for (i = 0; !(bitmask & 1); i++)
|
||||
bitmask >>= 1;
|
||||
|
||||
if (i >= MAX_STATE_BITS)
|
||||
continue;
|
||||
|
||||
save_states[i] = sym->str[0];
|
||||
}
|
||||
|
||||
return save_states;
|
||||
}
|
||||
|
||||
static struct tep_print_arg_field *
|
||||
find_arg_field(struct tep_format_field *prev_state_field, struct tep_print_arg *arg)
|
||||
{
|
||||
struct tep_print_arg_field *field;
|
||||
|
||||
if (!arg)
|
||||
return NULL;
|
||||
|
||||
if (arg->type == TEP_PRINT_FIELD)
|
||||
return &arg->field;
|
||||
|
||||
if (arg->type == TEP_PRINT_OP) {
|
||||
field = find_arg_field(prev_state_field, arg->op.left);
|
||||
if (field && field->field == prev_state_field)
|
||||
return field;
|
||||
field = find_arg_field(prev_state_field, arg->op.right);
|
||||
if (field && field->field == prev_state_field)
|
||||
return field;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct tep_print_flag_sym *
|
||||
test_flags(struct tep_format_field *prev_state_field, struct tep_print_arg *arg)
|
||||
{
|
||||
struct tep_print_arg_field *field;
|
||||
|
||||
field = find_arg_field(prev_state_field, arg->flags.field);
|
||||
if (!field)
|
||||
return NULL;
|
||||
|
||||
return arg->flags.flags;
|
||||
}
|
||||
|
||||
static struct tep_print_flag_sym *
|
||||
search_op(struct tep_format_field *prev_state_field, struct tep_print_arg *arg)
|
||||
{
|
||||
struct tep_print_flag_sym *sym = NULL;
|
||||
|
||||
if (!arg)
|
||||
return NULL;
|
||||
|
||||
if (arg->type == TEP_PRINT_OP) {
|
||||
sym = search_op(prev_state_field, arg->op.left);
|
||||
if (sym)
|
||||
return sym;
|
||||
|
||||
sym = search_op(prev_state_field, arg->op.right);
|
||||
if (sym)
|
||||
return sym;
|
||||
} else if (arg->type == TEP_PRINT_FLAGS) {
|
||||
sym = test_flags(prev_state_field, arg);
|
||||
}
|
||||
|
||||
return sym;
|
||||
}
|
||||
|
||||
const char *parse_task_states(struct tep_format_field *state_field)
|
||||
{
|
||||
struct tep_print_flag_sym *sym;
|
||||
struct tep_print_arg *arg;
|
||||
struct tep_event *event;
|
||||
|
||||
event = state_field->event;
|
||||
|
||||
/*
|
||||
* Look at the event format fields, and search for where
|
||||
* the prev_state is parsed via the format flags.
|
||||
*/
|
||||
for (arg = event->print_fmt.args; arg; arg = arg->next) {
|
||||
/*
|
||||
* Currently, the __print_flags() for the prev_state
|
||||
* is embedded in operations, so they too must be
|
||||
* searched.
|
||||
*/
|
||||
sym = search_op(state_field, arg);
|
||||
if (sym)
|
||||
return convert_sym(sym);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void parse_ftrace_printk(struct tep_handle *pevent,
|
||||
char *file, unsigned int size __maybe_unused)
|
||||
{
|
||||
|
@ -15,6 +15,7 @@ struct perf_tool;
|
||||
struct thread;
|
||||
struct tep_plugin_list;
|
||||
struct evsel;
|
||||
struct tep_format_field;
|
||||
|
||||
struct trace_event {
|
||||
struct tep_handle *pevent;
|
||||
@ -51,6 +52,8 @@ int parse_event_file(struct tep_handle *pevent,
|
||||
unsigned long long
|
||||
raw_field_value(struct tep_event *event, const char *name, void *data);
|
||||
|
||||
const char *parse_task_states(struct tep_format_field *state_field);
|
||||
|
||||
void parse_proc_kallsyms(struct tep_handle *pevent, char *file, unsigned int size);
|
||||
void parse_ftrace_printk(struct tep_handle *pevent, char *file, unsigned int size);
|
||||
void parse_saved_cmdline(struct tep_handle *pevent, char *file, unsigned int size);
|
||||
|
Loading…
Reference in New Issue
Block a user