-
Notifications
You must be signed in to change notification settings - Fork 5
Support associating BPF programs with struct_ops #6288
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support associating BPF programs with struct_ops #6288
Conversation
|
Upstream branch: 11369e6 |
fe98223 to
6fe2c31
Compare
|
Upstream branch: efa4756 |
b793679 to
d020aa1
Compare
6fe2c31 to
634398c
Compare
Allow verifier to fixup kfuncs in kernel module to support kfuncs with __prog arguments. Currently, special kfuncs and kfuncs with __prog arguments are kernel kfuncs. Allowing kernel module kfuncs should not affect existing kfunc fixup as kernel module kfuncs have BTF IDs greater than kernel kfuncs' BTF IDs. Signed-off-by: Amery Hung <[email protected]>
Add a new BPF command BPF_PROG_ASSOC_STRUCT_OPS to allow associating a BPF program with a struct_ops map. This command takes a file descriptor of a struct_ops map and a BPF program and set prog->aux->st_ops_assoc to the kdata of the struct_ops map. The command does not accept a struct_ops program nor a non-struct_ops map. Programs of a struct_ops map is automatically associated with the map during map update. If a program is shared between two struct_ops maps, prog->aux->st_ops_assoc will be poisoned to indicate that the associated struct_ops is ambiguous. The pointer, once poisoned, cannot be reset since we have lost track of associated struct_ops. For other program types, the associated struct_ops map, once set, cannot be changed later. This restriction may be lifted in the future if there is a use case. A kernel helper bpf_prog_get_assoc_struct_ops() can be used to retrieve the associated struct_ops pointer. The returned pointer, if not NULL, is guaranteed to be valid and point to a fully updated struct_ops struct. For struct_ops program reused in multiple struct_ops map, the return will be NULL. To make sure the returned pointer to be valid, the command increases the refcount of the map for every associated non-struct_ops programs. For struct_ops programs, the destruction of a struct_ops map already waits for its BPF programs to finish running. A later patch will further make sure the map will not be freed when an async callback schedule from struct_ops is running. struct_ops implementers should note that the struct_ops returned may or may not be attached. The struct_ops implementer will be responsible for tracking and checking the state of the associated struct_ops map if the use case requires an attached struct_ops. Signed-off-by: Amery Hung <[email protected]>
|
Upstream branch: b3387b3 |
Take a refcount of the associated struct_ops map to prevent the map from being freed when an async callback scheduled from a struct_ops program runs. Since struct_ops programs do not take refcounts on the struct_ops map, it is possible for a struct_ops map to be freed when an async callback scheduled from it runs. To prevent this, take a refcount on prog->aux-> st_ops_assoc and save it in a newly created struct bpf_async_res for every async mechanism. The reference needs to be preserved in bpf_async_res since prog->aux->st_ops_assoc can be poisoned anytime and reference leak could happen. bpf_async_res will contain a async callback's BPF program and resources related to the BPF program. The resources will be acquired when registering a callback and released when cancelled or when the map associated with the callback is freed. Also rename drop_prog_refcnt to bpf_async_cb_reset to better reflect what it now does. Signed-off-by: Amery Hung <[email protected]>
Add low-level wrapper and libbpf API for BPF_PROG_ASSOC_STRUCT_OPS command in the bpf() syscall. Signed-off-by: Amery Hung <[email protected]>
Test BPF_PROG_ASSOC_STRUCT_OPS command that associates a BPF program with a struct_ops. The test follows the same logic in commit ba7000f ("selftests/bpf: Test multi_st_ops and calling kfuncs from different programs"), but instead of using map id to identify a specific struct_ops, this test uses the new BPF command to associate a struct_ops with a program. The test consists of two sets of almost identical struct_ops maps and BPF programs associated with the map. Their only difference is the unique value returned by bpf_testmod_multi_st_ops::test_1(). The test first loads the programs and associates them with struct_ops maps. Then, it exercises the BPF programs. They will in turn call kfunc bpf_kfunc_multi_st_ops_test_1_prog_arg() to trigger test_1() of the associated struct_ops map, and then check if the right unique value is returned. Signed-off-by: Amery Hung <[email protected]>
Add a test to make sure implicit struct_ops association does not break backward compatibility nor return incorrect struct_ops. struct_ops programs should still be allowed to be reused in different struct_ops map. The associated struct_ops map set implicitly however will be poisoned. Trying to read it through the helper bpf_prog_get_assoc_struct_ops() should result in a NULL pointer. While recursion of test_1() cannot happen due to the associated struct_ops being ambiguois, explicitly check for it to prevent stack overflow if the test regresses. Signed-off-by: Amery Hung <[email protected]>
Make sure 1) a timer callback can also reference the associated struct_ops, and then make sure 2) the timer callback cannot get a dangled pointer to the struct_ops when the map is freed. The test schedules a timer callback from a struct_ops program since struct_ops programs do not pin the map. It is possible for the timer callback to run after the map is freed. The timer callback calls a kfunc that runs .test_1() of the associated struct_ops, which should return MAP_MAGIC when the map is still alive or -1 when the map is gone. The first subtest added in this patch schedules the timer callback to run immediately, while the map is still alive. The second subtest added schedules the callback to run 500ms after syscall_prog runs and then frees the map right after syscall_prog runs. Both subtests then wait until the callback runs to check the return of the kfunc. Signed-off-by: Amery Hung <[email protected]>
d020aa1 to
594bbd2
Compare
|
At least one diff in series https://patchwork.kernel.org/project/netdevbpf/list/?series=1019569 expired. Closing PR. |
Pull request for series with
subject: Support associating BPF programs with struct_ops
version: 5
url: https://patchwork.kernel.org/project/netdevbpf/list/?series=1019569