[RFC 12/12] perf event action: Add parsing builtin time expr support

Yang Jihong
2024-11-28T13:37:23Z

Support parsing of builtin time expression.

Testcase:
# perf record -e sched:sched_switch --action 'print("time = %llu\n", time)' true
time = 787661350481404
time = 787661350483823
time = 787661350493754
time = 787661350623109
time = 787661350482984
time = 787661350642538
time = 787661350647575
time = 787661350649706
time = 787661350650968
time = 787661350653686
time = 787661350654928
...
Signed-off-by: Yang Jihong <yangjihong@bytedance.com>
---
tools/perf/util/bpf_skel/bpf_record_action.h | 1 +
tools/perf/util/bpf_skel/record_action.bpf.c | 14 ++++++++++++++
tools/perf/util/parse-action.c | 1 +
tools/perf/util/parse-action.h | 1 +
tools/perf/util/parse-action.l | 1 +
tools/perf/util/record_action.c | 4 ++++
6 files changed, 22 insertions(+)

diff --git a/tools/perf/util/bpf_skel/bpf_record_action.h b/tools/perf/util/bpf_skel/bpf_record_action.h
index 325964b7aac9..e514ac14705e 100644
--- a/tools/perf/util/bpf_skel/bpf_record_action.h
+++ b/tools/perf/util/bpf_skel/bpf_record_action.h
@@ -11,6 +11,7 @@ enum __output_format_type {
__OUTPUT_FORMAT_TYPE_PID,
__OUTPUT_FORMAT_TYPE_TID,
__OUTPUT_FORMAT_TYPE_COMM,
+ __OUTPUT_FORMAT_TYPE_TIME,
__OUTPUT_FORMAT_TYPE_MAX,
};

diff --git a/tools/perf/util/bpf_skel/record_action.bpf.c b/tools/perf/util/bpf_skel/record_action.bpf.c
index f809305b16be..ed36f121e90b 100644
--- a/tools/perf/util/bpf_skel/record_action.bpf.c
+++ b/tools/perf/util/bpf_skel/record_action.bpf.c
@@ -84,6 +84,17 @@ static inline int output_comm(__u8 *data, int size)
return __TASK_COMM_MAX_SIZE;
}

+static inline int output_time(__u8 *data, int size)
+{
+ __u64 *ts = (__u64 *)data;
+
+ if (size < sizeof(__u64))
+ return -1;
+
+ *ts = bpf_ktime_get_ns();
+ return sizeof(__u64);
+}
+
SEC("xxx")
int sample_output(u64 *ctx)
{
@@ -115,6 +126,9 @@ int sample_output(u64 *ctx)
case __OUTPUT_FORMAT_TYPE_COMM:
ret = output_comm(data + total, __OUTPUT_DATA_MAX_SIZE - total);
break;
+ case __OUTPUT_FORMAT_TYPE_TIME:
+ ret = output_time(data + total, __OUTPUT_DATA_MAX_SIZE - total);
+ break;
default:
ret = -1;
break;
diff --git a/tools/perf/util/parse-action.c b/tools/perf/util/parse-action.c
index 8bc1646abe27..4f40e4a24357 100644
--- a/tools/perf/util/parse-action.c
+++ b/tools/perf/util/parse-action.c
@@ -16,6 +16,7 @@
* - pid
* - tid
* - comm
+ * - time
*/

#include <regex.h>
diff --git a/tools/perf/util/parse-action.h b/tools/perf/util/parse-action.h
index 39fb521f3193..57df6f8294f5 100644
--- a/tools/perf/util/parse-action.h
+++ b/tools/perf/util/parse-action.h
@@ -31,6 +31,7 @@ enum evtact_expr_builtin_type {
EVTACT_EXPR_BUILTIN_TYPE_PID,
EVTACT_EXPR_BUILTIN_TYPE_TID,
EVTACT_EXPR_BUILTIN_TYPE_COMM,
+ EVTACT_EXPR_BUILTIN_TYPE_TIME,
EVTACT_EXPR_BUILTIN_TYPE_MAX,
};

diff --git a/tools/perf/util/parse-action.l b/tools/perf/util/parse-action.l
index ddac305c1ca4..9029ac19c128 100644
--- a/tools/perf/util/parse-action.l
+++ b/tools/perf/util/parse-action.l
@@ -107,6 +107,7 @@ cpu { return builtin(EVTACT_EXPR_BUILTIN_TYPE_CPU); }
pid { return builtin(EVTACT_EXPR_BUILTIN_TYPE_PID); }
tid { return builtin(EVTACT_EXPR_BUILTIN_TYPE_TID); }
comm { return builtin(EVTACT_EXPR_BUILTIN_TYPE_COMM); }
+time { return builtin(EVTACT_EXPR_BUILTIN_TYPE_TIME); }

print { return call(EVTACT_EXPR_CALL_TYPE_PRINT); }

diff --git a/tools/perf/util/record_action.c b/tools/perf/util/record_action.c
index ead7eeffb7cc..4de6afcbfb26 100644
--- a/tools/perf/util/record_action.c
+++ b/tools/perf/util/record_action.c
@@ -108,6 +108,10 @@ static int set_expr_builtin_output_format(struct evtact_expr *expr,
*format = __OUTPUT_FORMAT_TYPE_COMM;
size = __TASK_COMM_MAX_SIZE;
break;
+ case EVTACT_EXPR_BUILTIN_TYPE_TIME:
+ *format = __OUTPUT_FORMAT_TYPE_TIME;
+ size = sizeof(u64);
+ break;
default:
pr_err("set expr builtin output format unknown opcode: %u\n", opcode);
return -1;
--
2.25.1