From: Steven Rostedt (VMware) <rostedt@xxxxxxxxxxx> In order to move pointer checks like IS_ERR_VALUE() out of the hotpath and into the reader path of a trace event, user space tools need to be able to parse that. IS_ERR_VALUE() is defined as: #define IS_ERR_VALUE() unlikely((unsigned long)(void *)(x) >= (unsigned long)-MAX_ERRNO) Which eventually turns into: __builtin_expect(!!((unsigned long)(void *)(x) >= (unsigned long)-4095), 0) Now the traceevent parser can handle most of that except for the __builtin_expect(), which needs to be added. Link: https://lore.kernel.org/linux-mm/20200320055823.27089-3-jaewon31.kim@xxxxxxxxxxx/ Signed-off-by: Steven Rostedt (VMware) <rostedt@xxxxxxxxxxx> Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> Cc: Jaewon Kim <jaewon31.kim@xxxxxxxxxxx> Cc: Jiri Olsa <jolsa@xxxxxxxxxx> Cc: Kees Kook <keescook@xxxxxxxxxxxx> Cc: Namhyung Kim <namhyung@xxxxxxxxxx> Cc: Vlastimil Babka <vbabka@xxxxxxx> Cc: linux-mm@xxxxxxxxx Cc: linux-trace-devel@xxxxxxxxxxxxxxx Link: http://lore.kernel.org/lkml/20200324200956.821799393@xxxxxxxxxxx Signed-off-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx> Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@xxxxxxxxx> --- lib/traceevent/event-parse.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/lib/traceevent/event-parse.c b/lib/traceevent/event-parse.c index 7e9cd9bb..ee16be96 100644 --- a/lib/traceevent/event-parse.c +++ b/lib/traceevent/event-parse.c @@ -3084,6 +3084,37 @@ err: return TEP_EVENT_ERROR; } +static enum tep_event_type +process_builtin_expect(struct tep_event *event, struct tep_print_arg *arg, char **tok) +{ + enum tep_event_type type; + char *token = NULL; + + /* Handle __builtin_expect( cond, #) */ + type = process_arg(event, arg, &token); + + if (type != TEP_EVENT_DELIM || token[0] != ',') + goto out_free; + + free_token(token); + + /* We don't care what the second parameter is of the __builtin_expect() */ + if (read_expect_type(TEP_EVENT_ITEM, &token) < 0) + goto out_free; + + if (read_expected(TEP_EVENT_DELIM, ")") < 0) + goto out_free; + + free_token(token); + type = read_token_item(tok); + return type; + +out_free: + free_token(token); + *tok = NULL; + return TEP_EVENT_ERROR; +} + static enum tep_event_type process_function(struct tep_event *event, struct tep_print_arg *arg, char *token, char **tok) @@ -3128,6 +3159,10 @@ process_function(struct tep_event *event, struct tep_print_arg *arg, free_token(token); return process_dynamic_array_len(event, arg, tok); } + if (strcmp(token, "__builtin_expect") == 0) { + free_token(token); + return process_builtin_expect(event, arg, tok); + } func = find_func_handler(event->tep, token); if (func) { -- 2.26.2