@@ -244,6 +244,7 @@ enum tep_print_arg_type {
TEP_PRINT_BITMASK,
TEP_PRINT_DYNAMIC_ARRAY_LEN,
TEP_PRINT_HEX_STR,
+ TEP_PRINT_CPUMASK,
};
struct tep_print_arg {
@@ -1120,6 +1120,7 @@ static void free_arg(struct tep_print_arg *arg)
free(arg->string.string);
break;
case TEP_PRINT_BITMASK:
+ case TEP_PRINT_CPUMASK:
free(arg->bitmask.bitmask);
break;
case TEP_PRINT_DYNAMIC_ARRAY:
@@ -2853,6 +2854,7 @@ static int arg_num_eval(struct tep_print_arg *arg, long long *val)
case TEP_PRINT_STRING:
case TEP_PRINT_BSTRING:
case TEP_PRINT_BITMASK:
+ case TEP_PRINT_CPUMASK:
default:
do_warning("invalid eval type %d", arg->type);
ret = 0;
@@ -2882,6 +2884,7 @@ static char *arg_eval (struct tep_print_arg *arg)
case TEP_PRINT_STRING:
case TEP_PRINT_BSTRING:
case TEP_PRINT_BITMASK:
+ case TEP_PRINT_CPUMASK:
default:
do_warning("invalid eval type %d", arg->type);
break;
@@ -3362,6 +3365,17 @@ process_bitmask(struct tep_event *event __maybe_unused, struct tep_print_arg *ar
return TEP_EVENT_ERROR;
}
+static enum tep_event_type
+process_cpumask(struct tep_event *event __maybe_unused, struct tep_print_arg *arg,
+ char **tok)
+{
+ enum tep_event_type type = process_bitmask(event, arg, tok);
+ if (type != TEP_EVENT_ERROR)
+ arg->type = TEP_PRINT_CPUMASK;
+
+ return type;
+}
+
static struct tep_function_handler *
find_func_handler(struct tep_handle *tep, char *func_name)
{
@@ -3521,6 +3535,11 @@ process_function(struct tep_event *event, struct tep_print_arg *arg,
free_token(token);
return process_bitmask(event, arg, tok);
}
+ if (strcmp(token, "__get_cpumask") == 0 ||
+ strcmp(token, "__get_rel_cpumask") == 0) {
+ free_token(token);
+ return process_cpumask(event, arg, tok);
+ }
if (strcmp(token, "__get_dynamic_array") == 0 ||
strcmp(token, "__get_rel_dynamic_array") == 0 ||
strcmp(token, "__get_sockaddr") == 0 ||
@@ -4181,6 +4200,7 @@ eval_num_arg(void *data, int size, struct tep_event *event, struct tep_print_arg
case TEP_PRINT_STRING:
case TEP_PRINT_BSTRING:
case TEP_PRINT_BITMASK:
+ case TEP_PRINT_CPUMASK:
return 0;
case TEP_PRINT_FUNC: {
struct trace_seq s;
@@ -4674,6 +4694,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
case TEP_PRINT_BSTRING:
print_str_to_seq(s, format, len_arg, arg->string.string);
break;
+ case TEP_PRINT_CPUMASK:
case TEP_PRINT_BITMASK: {
if (!arg->bitmask.field) {
arg->bitmask.field = tep_find_any_field(event, arg->bitmask.bitmask);
@@ -7196,6 +7217,9 @@ static void print_args(struct tep_print_arg *args)
case TEP_PRINT_BITMASK:
printf("__get_bitmask(%s)", args->bitmask.bitmask);
break;
+ case TEP_PRINT_CPUMASK:
+ printf("__get_cpumask(%s)", args->bitmask.bitmask);
+ break;
case TEP_PRINT_TYPE:
printf("(%s)", args->typecast.type);
print_args(args->typecast.item);
A cpumask event field type was recently added to Linux, which helps distinguish any odd bitmask from a cpumask. Right now this field type is not recognized by libtraceevent: [ipi:ipi_send_cpumask] function __get_cpumask not defined CPU 0 is empty CPU 1 is empty CPU 3 is empty cpus=4 echo-173 [002] 11.859745: ipi_send_cpumask: [FAILED TO PARSE] cpumask=ARRAY[02, 00, 00, 00, 00, 00, 00, 00] callsite=0xffffffff81121013 Since a cpumask is still a bitmask, define the boiler plate code for this new field type and wire it all to bitmask handling. Signed-off-by: Valentin Schneider <vschneid@redhat.com> --- include/traceevent/event-parse.h | 1 + src/event-parse.c | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+)