-
Notifications
You must be signed in to change notification settings - Fork 94
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
bpf: Add batch support for attaching trampolines #2158
Conversation
Master branch: dd7f091 |
Master branch: 29ad850 |
bbd0d9a
to
8eacd37
Compare
Now when we have *direct_multi interface the direct_functions hash is no longer owned just by direct_ops. It's also used by any other ftrace_ops passed to *direct_multi interface. Thus to find out that we are unregistering the last function from direct_ops, we need to check directly direct_ops's hash. Cc: Steven Rostedt <srostedt@vmware.com> Fixes: f64dd46 ("ftrace: Add multi direct register/unregister interface") Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Adding ops cleanup to unregister_ftrace_direct_multi, so it can be reused in another register call. Cc: Steven Rostedt <srostedt@vmware.com> Fixes: f64dd46 ("ftrace: Add multi direct register/unregister interface") Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Adding ftrace_set_filter_ips function to be able to set filter on multiple ip addresses at once. With the *direct_multi interface we have cases where we need to initialize ftrace_ops object with thousands of functions, so having single function diving into ftrace_hash_move_and_update_ops with ftrace_lock is better. The functions ips are passed as unsigned ong array with count. Cc: Steven Rostedt <srostedt@vmware.com> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Separating the check itself from model distilling and address search into __bpf_check_attach_target function. This way we can easily add function in following patch that gets only function model without the address search, while using the same code as bpf_check_attach_target. Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Adding bpf_check_attach_model function that returns model for function specified by btf_id. It will be used in following patches. Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Adding bpf_arg/bpf_ret_value helpers for tracing programs that returns traced function arguments. Get n-th argument of the traced function: long bpf_arg(void *ctx, int n) Get return value of the traced function: long bpf_ret_value(void *ctx) The trampoline now stores number of arguments on ctx-8 address, so it's easy to verify argument index and find return value argument. Moving function ip address on the trampoline stack behind the number of functions arguments, so it's now stored on ctx-16 address. Both helpers are inlined by verifier. Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Currently we call the original function by using the absolute address given at the JIT generation. That's not usable when having trampoline attached to multiple functions. In this case we need to take the return address from the stack. Adding support to retrieve the original function address from the stack by adding new BPF_TRAMP_F_ORIG_STACK flag for arch_prepare_bpf_trampoline function. Basically we take the return address of the 'fentry' call: function + 0: call fentry # stores 'function + 5' address on stack function + 5: ... The 'function + 5' address will be used as the address for the original function to call. Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Keeping active attached trampoline in bpf_prog so it can be used in following changes to account for multiple functions attachments in program. As EXT programs are not going to be supported in multiple functions attachment for now, I'm keeping them stored in link. Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Adding support to load tracing program with new BPF_F_MULTI_FUNC flag, that allows the program to be loaded without specific function to be attached to. Such program will be allowed to be attached to multiple functions in following patches. Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Replacing the bpf_trampoline's key with struct bpf_tramp_id object, that currently holds only obj_id/btf_id, so same data as key. Having the key in the struct will allow us to add more ids (functions) to single trampoline in following patches. No functional change is intended. Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Adding addr to bpf_trampoline_id object so it's not associated directly with trampoline directly. This will help us to easily support multiple ids/addresses support for trampolines coming in following changes. Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Currently each trampoline holds a list of programs that are attached to it. With multi func attach support we need a way for a single program to be connected to multiple trampolines. Adding struct bpf_tramp_node object that holds bpf_prog pointer, so it can be resolved directly. We can now have multiple struct bpf_tramp_node being attached to different trampolines pointing to single bpf_prog. Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Adding bpf_tramp_attach layer for trampoline attachment to have extra layer on top of the trampoline. The reason is that in following changes we will add multiple trampolines for single program and we need entity to hold them. The api in nutshell: - each bpf_prog holds 'bpf_tramp_attach' object, which holds list of 'struct bpf_tramp_node' objects: struct bpf_tramp_attach { struct bpf_tramp_id *id; struct hlist_head nodes; }; This allow us to hold multiple trampolines for each program. - bpf_tramp_attach returns 'bpf_tramp_attach' object that finds trampoline for given 'id' and adds it to the attach object, no actuall program attachment is done, just trampoline allocation - bpf_tramp_attach_link does the actual attachment of the program to trampoline - bpf_tramp_attach_unlink unlinks all the trampolines present in the attach object - bpf_tramp_detach frees all the trampolines in attach object Currently there'll be only single node added in attach object. Following patches add support for multiple id trampolines, and uses multiple nodes in attach object to hold trampoline for given program. Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Adding support to store multiple ids in bpf_tramp_id object, to have id for trampolines with multiple functions assigned. Extra array of u32 values is allocated within bpf_tramp_id object allocation. Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Adding support to store multiple addrs in bpf_tramp_id object, to provide address values for id values stored in the object. The id->addr[idx] returns address value for id->id[idx] id. Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Adding bpf_tramp_id_single function as interface to create trampoline with single ID and grouping together the trampoline allocation with init that is used on several places and save us few lines. Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Moving the id resolving in the bpf_tramp_id_single function so it's centralized together with the trampoline's allocation and init. Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Adding refcount_t to struct bpf_tramp_id so we can track its allocation and safely use one object on more places in following changes. Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Adding support to attach trampolines with multiple IDs. This patch adds support to bpf_tramp_attach function to attach given program to bpf_tramp_id object that holds multiple BTF function IDs. The process of attaching in bpf_tramp_attach is as follows: - IDs in bpf_tramp_id object are sorted out to several new bpf_tramp_id objects based on number of arguments of each ID - so we end up with up to 6 bpf_tramp_id objects, that we will create or find suitable trampoline for - separating function IDs that have same number of arguments save us troubles of handling different argument counts within one trampoline - now for each such bpf_tramp_id object we do following: * search existing trampolines to find match or intersection * if there's full match on IDs, we add program to existing trampoline and we are done * if there's intersection with existing trampoline, we split it and add new program to the common part, the rest of the IDs are attached to new trampoline - we keep trampoline_table as place holder for all trampolines, (while the has works only for single ID trampolines) so in case there is no multi-id trampoline defined, we still use the fast hash trampoline lookup The bpf_tramp_attach assumes ID array is coming in sorted so it's possible to run bsearch on it to do all the needed searches. The splitting of the trampoline use the fact that we carry 'bpf_tramp_attach' object for each bpf_program, so when we split trampoline that the program is attached to, we just add new 'bpf_tramp_node' object to the program's attach 'nodes'. This way we keep track of all program's trampolines and it will be properly detached when the program goes away. The splitting of the trampoline is done with following steps: - lock the trampoline - unregister trampoline - alloc the duplicate, which means that for all attached programs of the original trampoline we create new bpf_tramp_node objects and add them to these programs' attach objects - then we assign new IDs (common and the rest) to both (original and the duplicated) trampolines - register both trampolines - unlock the original trampoline This patch only adds bpf_tramp_attach support to attach multiple ID bpf_tramp_id object. The actual user interface for that comes in following patch. Now when each call to bpf_tramp_attach can change any program's attach object, we need to take trampoline_mutex in both bpf_tramp_attach_link and bpf_tramp_attach_unlink functions. Perhaps we could add new lock to bpf_tramp_attach object to get rid of single lock for all. Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Adding new link to allow to attach program to multiple function BTF IDs. New fields are added to bpf_attr::link_create to pass array of BTF IDs: struct { __aligned_u64 btf_ids; /* addresses to attach */ __u32 btf_ids_cnt; /* addresses count */ } multi; The new link code will load these IDs into bpf_tramp_id and resolve their ips. The resolve itself is done as per Andrii's suggestion: - lookup all names for given IDs - store and sort them by name - go through all kallsyms symbols and use bsearch to find it in provided names - if name is found, store the address for the name - resort the names array based on ID If there are multi symbols of the same name the first one will be used to resolve the address. The new link will pass them to the bpf_tramp_attach that does all the work of attaching. Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Adding btf__find_by_glob_kind function that returns array of BTF ids that match given kind and allow/deny patterns. int btf__find_by_glob_kind(const struct btf *btf, __u32 kind, const char *allow_pattern, const char *deny_pattern, __u32 **__ids); The __ids array is allocated and needs to be manually freed. At the moment the supported pattern is '*' at the beginning or the end of the pattern. Kindly borrowed from retsnoop. Suggested-by: Andrii Nakryiko <andrii.nakryiko@gmail.com> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Adding support to link multi func tracing program through link_create interface. Adding special types for multi func programs: fentry.multi fexit.multi so you can define multi func programs like: SEC("fentry.multi/bpf_fentry_test*") int BPF_PROG(test1, __u64 a, __u64 b, __u64 c, __u64 d, __u64 e, __u64 f) that defines test1 to be attached to bpf_fentry_test* functions. The test1 program is loaded with BPF_F_MULTI_FUNC flag. If functions are not specified the program needs to be attached manually. Adding new btf_ids/btf_ids_cnt fields to bpf_link_create_opts, that define functions to attach the program to. Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Adding tests for bpf_arg/bpf_ret_value helpers on both fentry and fexit programs. Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Adding selftest for fentry multi func test that attaches to bpf_fentry_test* functions and checks argument values based on the processed function. We need to cast to real arguments types in multi_arg_check, because the checked value can be shorter than u64. Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Adding selftest for fexit multi func test that attaches to bpf_fentry_test* functions and checks argument values based on the processed function. Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Adding selftest for fentry/fexit multi func tests that attaches to bpf_fentry_test* functions and checks argument values based on the processed function. Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Adding selftest for fentry/fexit multi func tests that attaches to bpf_fentry_test* functions, where some of them have already attached trampoline. Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Adding extra test to existing modify_return test to test this with multi func program attached on top of the modify return program. Because the supported wildcards do not allow us to match both bpf_fentry_test* and bpf_modify_return_test, adding extra code to look it up in kernel's BTF. Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Adding test code to check on trampolines spliting. The tests attached various bpf_fetry_* functions in a way so there's always non trivial IDs intersection, that leads to trampoline splitting in kenrel code. Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Master branch: 7615209 |
8eacd37
to
dcb00eb
Compare
At least one diff in series https://patchwork.kernel.org/project/netdevbpf/list/?series=582267 expired. Closing PR. |
Pull request for series with
subject: bpf: Add batch support for attaching trampolines
version: 5
url: https://patchwork.kernel.org/project/netdevbpf/list/?series=582267