Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

authored by

Ze Gao and committed by
Namhyung Kim
20018398 7727d59d

+120 -115
+1 -1
tools/perf/Makefile.perf
··· 370 370 ifeq ($(CONFIG_LIBTRACEEVENT),y) 371 371 PYTHON_EXT_SRCS := $(shell grep -v ^\# util/python-ext-sources) 372 372 else 373 - PYTHON_EXT_SRCS := $(shell grep -v ^\#\\\|util/trace-event.c util/python-ext-sources) 373 + PYTHON_EXT_SRCS := $(shell grep -v ^\#\\\|util/trace-event.c\\\|util/trace-event-parse.c util/python-ext-sources) 374 374 endif 375 375 376 376 PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBAPI)
+1 -114
tools/perf/util/evsel.c
··· 2851 2851 return field ? format_field__intval(field, sample, evsel->needs_swap) : 0; 2852 2852 } 2853 2853 2854 - /* 2855 - * prev_state is of size long, which is 32 bits on 32 bit architectures. 2856 - * As it needs to have the same bits for both 32 bit and 64 bit architectures 2857 - * we can just assume that the flags we care about will all be within 2858 - * the 32 bits. 2859 - */ 2860 - #define MAX_STATE_BITS 32 2861 - 2862 - static const char *convert_sym(struct tep_print_flag_sym *sym) 2863 - { 2864 - static char save_states[MAX_STATE_BITS + 1]; 2865 - 2866 - memset(save_states, 0, sizeof(save_states)); 2867 - 2868 - /* This is the flags for the prev_state_field, now make them into a string */ 2869 - for (; sym; sym = sym->next) { 2870 - long bitmask = strtoul(sym->value, NULL, 0); 2871 - int i; 2872 - 2873 - for (i = 0; !(bitmask & 1); i++) 2874 - bitmask >>= 1; 2875 - 2876 - if (i >= MAX_STATE_BITS) 2877 - continue; 2878 - 2879 - save_states[i] = sym->str[0]; 2880 - } 2881 - 2882 - return save_states; 2883 - } 2884 - 2885 - static struct tep_print_arg_field * 2886 - find_arg_field(struct tep_format_field *prev_state_field, struct tep_print_arg *arg) 2887 - { 2888 - struct tep_print_arg_field *field; 2889 - 2890 - if (!arg) 2891 - return NULL; 2892 - 2893 - if (arg->type == TEP_PRINT_FIELD) 2894 - return &arg->field; 2895 - 2896 - if (arg->type == TEP_PRINT_OP) { 2897 - field = find_arg_field(prev_state_field, arg->op.left); 2898 - if (field && field->field == prev_state_field) 2899 - return field; 2900 - field = find_arg_field(prev_state_field, arg->op.right); 2901 - if (field && field->field == prev_state_field) 2902 - return field; 2903 - } 2904 - return NULL; 2905 - } 2906 - 2907 - static struct tep_print_flag_sym * 2908 - test_flags(struct tep_format_field *prev_state_field, struct tep_print_arg *arg) 2909 - { 2910 - struct tep_print_arg_field *field; 2911 - 2912 - field = find_arg_field(prev_state_field, arg->flags.field); 2913 - if (!field) 2914 - return NULL; 2915 - 2916 - return arg->flags.flags; 2917 - } 2918 - 2919 - static struct tep_print_flag_sym * 2920 - search_op(struct tep_format_field *prev_state_field, struct tep_print_arg *arg) 2921 - { 2922 - struct tep_print_flag_sym *sym = NULL; 2923 - 2924 - if (!arg) 2925 - return NULL; 2926 - 2927 - if (arg->type == TEP_PRINT_OP) { 2928 - sym = search_op(prev_state_field, arg->op.left); 2929 - if (sym) 2930 - return sym; 2931 - 2932 - sym = search_op(prev_state_field, arg->op.right); 2933 - if (sym) 2934 - return sym; 2935 - } else if (arg->type == TEP_PRINT_FLAGS) { 2936 - sym = test_flags(prev_state_field, arg); 2937 - } 2938 - 2939 - return sym; 2940 - } 2941 - 2942 - static const char *get_states(struct tep_format_field *prev_state_field) 2943 - { 2944 - struct tep_print_flag_sym *sym; 2945 - struct tep_print_arg *arg; 2946 - struct tep_event *event; 2947 - 2948 - event = prev_state_field->event; 2949 - 2950 - /* 2951 - * Look at the event format fields, and search for where 2952 - * the prev_state is parsed via the format flags. 2953 - */ 2954 - for (arg = event->print_fmt.args; arg; arg = arg->next) { 2955 - /* 2956 - * Currently, the __print_flags() for the prev_state 2957 - * is embedded in operations, so they too must be 2958 - * searched. 2959 - */ 2960 - sym = search_op(prev_state_field, arg); 2961 - if (sym) 2962 - return convert_sym(sym); 2963 - } 2964 - return NULL; 2965 - } 2966 - 2967 2854 char evsel__taskstate(struct evsel *evsel, struct perf_sample *sample, const char *name) 2968 2855 { 2969 2856 static struct tep_format_field *prev_state_field; ··· 2866 2979 return state; 2867 2980 2868 2981 if (!states || field != prev_state_field) { 2869 - states = get_states(field); 2982 + states = parse_task_states(field); 2870 2983 if (!states) 2871 2984 return state; 2872 2985 prev_state_field = field;
+1
tools/perf/util/python-ext-sources
··· 31 31 util/print_binary.c 32 32 util/strlist.c 33 33 util/trace-event.c 34 + util/trace-event-parse.c 34 35 ../lib/rbtree.c 35 36 util/string.c 36 37 util/symbol_fprintf.c
+1
tools/perf/util/setup.py
··· 85 85 extra_libraries += [ 'traceevent' ] 86 86 else: 87 87 ext_sources.remove('util/trace-event.c') 88 + ext_sources.remove('util/trace-event-parse.c') 88 89 89 90 # use full paths with source files 90 91 ext_sources = list(map(lambda x: '%s/%s' % (src_perf, x) , ext_sources))
+113
tools/perf/util/trace-event-parse.c
··· 122 122 return event_format__fprintf(event, cpu, data, size, stdout); 123 123 } 124 124 125 + /* 126 + * prev_state is of size long, which is 32 bits on 32 bit architectures. 127 + * As it needs to have the same bits for both 32 bit and 64 bit architectures 128 + * we can just assume that the flags we care about will all be within 129 + * the 32 bits. 130 + */ 131 + #define MAX_STATE_BITS 32 132 + 133 + static const char *convert_sym(struct tep_print_flag_sym *sym) 134 + { 135 + static char save_states[MAX_STATE_BITS + 1]; 136 + 137 + memset(save_states, 0, sizeof(save_states)); 138 + 139 + /* This is the flags for the prev_state_field, now make them into a string */ 140 + for (; sym; sym = sym->next) { 141 + long bitmask = strtoul(sym->value, NULL, 0); 142 + int i; 143 + 144 + for (i = 0; !(bitmask & 1); i++) 145 + bitmask >>= 1; 146 + 147 + if (i >= MAX_STATE_BITS) 148 + continue; 149 + 150 + save_states[i] = sym->str[0]; 151 + } 152 + 153 + return save_states; 154 + } 155 + 156 + static struct tep_print_arg_field * 157 + find_arg_field(struct tep_format_field *prev_state_field, struct tep_print_arg *arg) 158 + { 159 + struct tep_print_arg_field *field; 160 + 161 + if (!arg) 162 + return NULL; 163 + 164 + if (arg->type == TEP_PRINT_FIELD) 165 + return &arg->field; 166 + 167 + if (arg->type == TEP_PRINT_OP) { 168 + field = find_arg_field(prev_state_field, arg->op.left); 169 + if (field && field->field == prev_state_field) 170 + return field; 171 + field = find_arg_field(prev_state_field, arg->op.right); 172 + if (field && field->field == prev_state_field) 173 + return field; 174 + } 175 + return NULL; 176 + } 177 + 178 + static struct tep_print_flag_sym * 179 + test_flags(struct tep_format_field *prev_state_field, struct tep_print_arg *arg) 180 + { 181 + struct tep_print_arg_field *field; 182 + 183 + field = find_arg_field(prev_state_field, arg->flags.field); 184 + if (!field) 185 + return NULL; 186 + 187 + return arg->flags.flags; 188 + } 189 + 190 + static struct tep_print_flag_sym * 191 + search_op(struct tep_format_field *prev_state_field, struct tep_print_arg *arg) 192 + { 193 + struct tep_print_flag_sym *sym = NULL; 194 + 195 + if (!arg) 196 + return NULL; 197 + 198 + if (arg->type == TEP_PRINT_OP) { 199 + sym = search_op(prev_state_field, arg->op.left); 200 + if (sym) 201 + return sym; 202 + 203 + sym = search_op(prev_state_field, arg->op.right); 204 + if (sym) 205 + return sym; 206 + } else if (arg->type == TEP_PRINT_FLAGS) { 207 + sym = test_flags(prev_state_field, arg); 208 + } 209 + 210 + return sym; 211 + } 212 + 213 + const char *parse_task_states(struct tep_format_field *state_field) 214 + { 215 + struct tep_print_flag_sym *sym; 216 + struct tep_print_arg *arg; 217 + struct tep_event *event; 218 + 219 + event = state_field->event; 220 + 221 + /* 222 + * Look at the event format fields, and search for where 223 + * the prev_state is parsed via the format flags. 224 + */ 225 + for (arg = event->print_fmt.args; arg; arg = arg->next) { 226 + /* 227 + * Currently, the __print_flags() for the prev_state 228 + * is embedded in operations, so they too must be 229 + * searched. 230 + */ 231 + sym = search_op(state_field, arg); 232 + if (sym) 233 + return convert_sym(sym); 234 + } 235 + return NULL; 236 + } 237 + 125 238 void parse_ftrace_printk(struct tep_handle *pevent, 126 239 char *file, unsigned int size __maybe_unused) 127 240 {
+3
tools/perf/util/trace-event.h
··· 15 15 struct thread; 16 16 struct tep_plugin_list; 17 17 struct evsel; 18 + struct tep_format_field; 18 19 19 20 struct trace_event { 20 21 struct tep_handle *pevent; ··· 51 50 52 51 unsigned long long 53 52 raw_field_value(struct tep_event *event, const char *name, void *data); 53 + 54 + const char *parse_task_states(struct tep_format_field *state_field); 54 55 55 56 void parse_proc_kallsyms(struct tep_handle *pevent, char *file, unsigned int size); 56 57 void parse_ftrace_printk(struct tep_handle *pevent, char *file, unsigned int size);