diff options
author | David Vernet <void@manifault.com> | 2023-03-31 14:57:33 -0500 |
---|---|---|
committer | Alexei Starovoitov <ast@kernel.org> | 2023-04-01 09:07:20 -0700 |
commit | db9d479ab59b21d719486e6bf673f83f129dae32 (patch) | |
tree | 62f3e2549846daec101886a9b5244428ff0aea3e /Documentation/bpf/kfuncs.rst | |
parent | f85671c6ef46d490a90dac719e0c0e0adbacfd9b (diff) | |
download | linux-stable-db9d479ab59b21d719486e6bf673f83f129dae32.tar.gz linux-stable-db9d479ab59b21d719486e6bf673f83f129dae32.tar.bz2 linux-stable-db9d479ab59b21d719486e6bf673f83f129dae32.zip |
bpf,docs: Update documentation to reflect new task kfuncs
Now that struct task_struct objects are RCU safe, and bpf_task_acquire()
can return NULL, we should update the BPF task kfunc documentation to
reflect the current state of the API.
Signed-off-by: David Vernet <void@manifault.com>
Link: https://lore.kernel.org/r/20230331195733.699708-4-void@manifault.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'Documentation/bpf/kfuncs.rst')
-rw-r--r-- | Documentation/bpf/kfuncs.rst | 49 |
1 files changed, 43 insertions, 6 deletions
diff --git a/Documentation/bpf/kfuncs.rst b/Documentation/bpf/kfuncs.rst index bf1b85941452..d8a16c4bef7f 100644 --- a/Documentation/bpf/kfuncs.rst +++ b/Documentation/bpf/kfuncs.rst @@ -471,13 +471,50 @@ struct_ops callback arg. For example: struct task_struct *acquired; acquired = bpf_task_acquire(task); + if (acquired) + /* + * In a typical program you'd do something like store + * the task in a map, and the map will automatically + * release it later. Here, we release it manually. + */ + bpf_task_release(acquired); + return 0; + } + + +References acquired on ``struct task_struct *`` objects are RCU protected. +Therefore, when in an RCU read region, you can obtain a pointer to a task +embedded in a map value without having to acquire a reference: + +.. code-block:: c + + #define private(name) SEC(".data." #name) __hidden __attribute__((aligned(8))) + private(TASK) static struct task_struct *global; + + /** + * A trivial example showing how to access a task stored + * in a map using RCU. + */ + SEC("tp_btf/task_newtask") + int BPF_PROG(task_rcu_read_example, struct task_struct *task, u64 clone_flags) + { + struct task_struct *local_copy; + + bpf_rcu_read_lock(); + local_copy = global; + if (local_copy) + /* + * We could also pass local_copy to kfuncs or helper functions here, + * as we're guaranteed that local_copy will be valid until we exit + * the RCU read region below. + */ + bpf_printk("Global task %s is valid", local_copy->comm); + else + bpf_printk("No global task found"); + bpf_rcu_read_unlock(); + + /* At this point we can no longer reference local_copy. */ - /* - * In a typical program you'd do something like store - * the task in a map, and the map will automatically - * release it later. Here, we release it manually. - */ - bpf_task_release(acquired); return 0; } |