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

Yang Jihong
2024-11-28T13:36:58Z

Support parsing of builtin cpu expression.

Testcase:
# perf record -e sched:sched_switch --action 'print("cpu = %d\n", cpu)'
cpu = 7
cpu = 7
cpu = 7
cpu = 7
cpu = 7
cpu = 7
cpu = 7
cpu = 7
cpu = 7
...
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 | 16 ++++++++++++++++
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 | 7 +++++--
6 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/bpf_skel/bpf_record_action.h b/tools/perf/util/bpf_skel/bpf_record_action.h
index ee4d03848e58..91a307b89f85 100644
--- a/tools/perf/util/bpf_skel/bpf_record_action.h
+++ b/tools/perf/util/bpf_skel/bpf_record_action.h
@@ -7,6 +7,7 @@
#define __OUTPUT_FORMATS_MAX_NUM 8

enum __output_format_type {
+ __OUTPUT_FORMAT_TYPE_CPU,
__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 424fa8c3e6f1..4b7698554ead 100644
--- a/tools/perf/util/bpf_skel/record_action.bpf.c
+++ b/tools/perf/util/bpf_skel/record_action.bpf.c
@@ -35,10 +35,22 @@ static inline struct __output_data_payload *sample_data_payload(void)
return bpf_map_lookup_elem(&sample_data_tmp, &key);
}

+static inline int output_cpu(__u8 *data, int size)
+{
+ __u32 *cpu = (__u32 *)data;
+
+ if (size < sizeof(__u32))
+ return -1;
+
+ *cpu = bpf_get_smp_processor_id();
+ return sizeof(__u32);
+}
+
SEC("xxx")
int sample_output(u64 *ctx)
{
struct __output_data_payload *sample;
+ __u8 *data;
int i;
int total = 0;
int ret = 0;
@@ -50,8 +62,12 @@ int sample_output(u64 *ctx)
if (!sample)
return 0;

+ data = sample->__data;
for (i = 0; i < output_format_num && i < __OUTPUT_FORMATS_MAX_NUM; i++) {
switch (output_formats[i]) {
+ case __OUTPUT_FORMAT_TYPE_CPU:
+ ret = output_cpu(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 e6299de99bc5..2bb32cc16ae7 100644
--- a/tools/perf/util/parse-action.c
+++ b/tools/perf/util/parse-action.c
@@ -12,6 +12,7 @@
* - call:
* - print
* - builtin:
+ * - cpu
*/

#include <regex.h>
diff --git a/tools/perf/util/parse-action.h b/tools/perf/util/parse-action.h
index b1a33a77c558..ee949ed07111 100644
--- a/tools/perf/util/parse-action.h
+++ b/tools/perf/util/parse-action.h
@@ -27,6 +27,7 @@ enum evtact_expr_call_type {
};

enum evtact_expr_builtin_type {
+ EVTACT_EXPR_BUILTIN_TYPE_CPU,
EVTACT_EXPR_BUILTIN_TYPE_MAX,
};

diff --git a/tools/perf/util/parse-action.l b/tools/perf/util/parse-action.l
index 1c729b7a0248..dab8066a1038 100644
--- a/tools/perf/util/parse-action.l
+++ b/tools/perf/util/parse-action.l
@@ -103,6 +103,7 @@ ident [_a-zA-Z][_a-zA-Z0-9]*
{num_hex} { return value(16); }
{space} { }

+cpu { return builtin(EVTACT_EXPR_BUILTIN_TYPE_CPU); }

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 634d6b199bae..15e8b1740e32 100644
--- a/tools/perf/util/record_action.c
+++ b/tools/perf/util/record_action.c
@@ -86,13 +86,16 @@ int bpf_perf_record_init(void)
}

static int set_expr_builtin_output_format(struct evtact_expr *expr,
- u32 opcode, int *offset,
- int *format __maybe_unused)
+ u32 opcode, int *offset, int *format)
{
int size = 0;
struct expr_builtin_output_priv *priv = expr->priv;

switch (opcode) {
+ case EVTACT_EXPR_BUILTIN_TYPE_CPU:
+ *format = __OUTPUT_FORMAT_TYPE_CPU;
+ size = sizeof(u32);
+ break;
default:
pr_err("set expr builtin output format unknown opcode: %u\n", opcode);
return -1;
--
2.25.1