Thread (19 messages) 19 messages, 5 authors, 2020-06-25

Re: [PATCH bpf-next 1/3] bpf: introduce helper bpf_get_task_stack_trace()

From: Alexei Starovoitov <hidden>
Date: 2020-06-23 15:19:20
Also in: bpf

On Tue, Jun 23, 2020 at 12:08 AM Song Liu [off-list ref] wrote:
quoted hunk ↗ jump to hunk
This helper can be used with bpf_iter__task to dump all /proc/*/stack to
a seq_file.

Signed-off-by: Song Liu <redacted>
---
 include/uapi/linux/bpf.h       | 10 +++++++++-
 kernel/trace/bpf_trace.c       | 21 +++++++++++++++++++++
 scripts/bpf_helpers_doc.py     |  2 ++
 tools/include/uapi/linux/bpf.h | 10 +++++++++-
 4 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 19684813faaed..a30416b822fe3 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -3252,6 +3252,13 @@ union bpf_attr {
  *             case of **BPF_CSUM_LEVEL_QUERY**, the current skb->csum_level
  *             is returned or the error code -EACCES in case the skb is not
  *             subject to CHECKSUM_UNNECESSARY.
+ *
+ * int bpf_get_task_stack_trace(struct task_struct *task, void *entries, u32 size)
+ *     Description
+ *             Save a task stack trace into array *entries*. This is a wrapper
+ *             over stack_trace_save_tsk().
+ *     Return
+ *             Number of trace entries stored.
  */
 #define __BPF_FUNC_MAPPER(FN)          \
        FN(unspec),                     \
@@ -3389,7 +3396,8 @@ union bpf_attr {
        FN(ringbuf_submit),             \
        FN(ringbuf_discard),            \
        FN(ringbuf_query),              \
-       FN(csum_level),
+       FN(csum_level),                 \
+       FN(get_task_stack_trace),

 /* integer value in 'imm' field of BPF_CALL instruction selects which helper
  * function eBPF program intends to call
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index e729c9e587a07..2c13bcb5c2bce 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -1488,6 +1488,23 @@ static const struct bpf_func_proto bpf_get_stack_proto_raw_tp = {
        .arg4_type      = ARG_ANYTHING,
 };

+BPF_CALL_3(bpf_get_task_stack_trace, struct task_struct *, task,
+          void *, entries, u32, size)
+{
+       return stack_trace_save_tsk(task, (unsigned long *)entries, size, 0);
+}
+
+static int bpf_get_task_stack_trace_btf_ids[5];
+static const struct bpf_func_proto bpf_get_task_stack_trace_proto = {
+       .func           = bpf_get_task_stack_trace,
+       .gpl_only       = true,
why?
+       .ret_type       = RET_INTEGER,
+       .arg1_type      = ARG_PTR_TO_BTF_ID,
+       .arg2_type      = ARG_PTR_TO_MEM,
+       .arg3_type      = ARG_CONST_SIZE_OR_ZERO,
OR_ZERO ? why?
quoted hunk ↗ jump to hunk
+       .btf_id         = bpf_get_task_stack_trace_btf_ids,
+};
+
 static const struct bpf_func_proto *
 raw_tp_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
 {
@@ -1521,6 +1538,10 @@ tracing_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
                return prog->expected_attach_type == BPF_TRACE_ITER ?
                       &bpf_seq_write_proto :
                       NULL;
+       case BPF_FUNC_get_task_stack_trace:
+               return prog->expected_attach_type == BPF_TRACE_ITER ?
+                       &bpf_get_task_stack_trace_proto :
why limit to iter only?
+ *
+ * int bpf_get_task_stack_trace(struct task_struct *task, void *entries, u32 size)
+ *     Description
+ *             Save a task stack trace into array *entries*. This is a wrapper
+ *             over stack_trace_save_tsk().
size is not documented and looks wrong.
the verifier checks it in bytes, but it's consumed as number of u32s.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help