55#include <search.h>
66#include "bpf/libbpf_internal.h"
77#include "tracing_multi.skel.h"
8+ #include "tracing_multi_intersect.skel.h"
89#include "trace_helpers.h"
910
1011static const char * bpf_fentry_test [] = {
@@ -18,6 +19,20 @@ static const char *bpf_fentry_test[] = {
1819 "bpf_fentry_test8" ,
1920};
2021
22+ static int get_random_funcs (const char * * funcs )
23+ {
24+ int i , cnt = 0 ;
25+
26+ for (i = 0 ; i < 8 ; i ++ ) {
27+ if (rand () % 2 )
28+ funcs [cnt ++ ] = bpf_fentry_test [i ];
29+ }
30+ /* we always need at least one.. */
31+ if (!cnt )
32+ funcs [cnt ++ ] = bpf_fentry_test [rand () % 8 ];
33+ return cnt ;
34+ }
35+
2136static int compare (const void * pa , const void * pb )
2237{
2338 return strcmp ((char * ) pa , (char * ) pb );
@@ -167,6 +182,82 @@ static void test_link_api_ids(void)
167182 tracing_multi__destroy (skel );
168183}
169184
185+ static bool is_set (__u32 mask , __u32 bit )
186+ {
187+ return (1 << bit ) & mask ;
188+ }
189+
190+ static void __test_intersect (__u32 mask , const struct bpf_program * progs [4 ], __u64 * test_results [4 ])
191+ {
192+ LIBBPF_OPTS (bpf_tracing_multi_opts , opts );
193+ LIBBPF_OPTS (bpf_test_run_opts , topts );
194+ struct bpf_link * links [4 ] = {};
195+ const char * funcs [8 ];
196+ __u64 expected [4 ];
197+ __u32 * ids , i ;
198+ int err , cnt ;
199+
200+ for (i = 0 ; i < 4 ; i ++ ) {
201+ if (!is_set (mask , i ))
202+ continue ;
203+
204+ cnt = get_random_funcs (funcs );
205+ ids = get_ids (funcs , cnt );
206+ if (!ASSERT_OK_PTR (ids , "get_ids" ))
207+ goto cleanup ;
208+
209+ opts .ids = ids ;
210+ opts .cnt = cnt ;
211+ links [i ] = bpf_program__attach_tracing_multi (progs [i ], NULL , & opts );
212+ free (ids );
213+
214+ if (!ASSERT_OK_PTR (links [i ], "bpf_program__attach_tracing_multi" ))
215+ goto cleanup ;
216+
217+ expected [i ] = * test_results [i ] + cnt ;
218+ }
219+
220+ err = bpf_prog_test_run_opts (bpf_program__fd (progs [0 ]), & topts );
221+ ASSERT_OK (err , "test_run" );
222+
223+ for (i = 0 ; i < 4 ; i ++ ) {
224+ if (!is_set (mask , i ))
225+ continue ;
226+ ASSERT_EQ (* test_results [i ], expected [i ], "test_results" );
227+ }
228+
229+ cleanup :
230+ for (i = 0 ; i < 4 ; i ++ )
231+ bpf_link__destroy (links [i ]);
232+ }
233+
234+ static void test_intersect (void )
235+ {
236+ const struct bpf_program * progs [4 ];
237+ struct tracing_multi_intersect * skel ;
238+ __u64 * test_results [4 ];
239+ __u32 i ;
240+
241+ skel = tracing_multi_intersect__open_and_load ();
242+ if (!ASSERT_OK_PTR (skel , "tracing_multi_intersect__open_and_load" ))
243+ return ;
244+
245+ progs [0 ] = skel -> progs .fentry_1 ;
246+ progs [1 ] = skel -> progs .fexit_1 ;
247+ progs [2 ] = skel -> progs .fentry_2 ;
248+ progs [3 ] = skel -> progs .fexit_2 ;
249+
250+ test_results [0 ] = & skel -> bss -> test_result_fentry_1 ;
251+ test_results [1 ] = & skel -> bss -> test_result_fexit_1 ;
252+ test_results [2 ] = & skel -> bss -> test_result_fentry_2 ;
253+ test_results [3 ] = & skel -> bss -> test_result_fexit_2 ;
254+
255+ for (i = 1 ; i < 16 ; i ++ )
256+ __test_intersect (i , progs , test_results );
257+
258+ tracing_multi_intersect__destroy (skel );
259+ }
260+
170261void test_tracing_multi_test (void )
171262{
172263#ifndef __x86_64__
@@ -180,4 +271,6 @@ void test_tracing_multi_test(void)
180271 test_link_api_pattern ();
181272 if (test__start_subtest ("link_api_ids" ))
182273 test_link_api_ids ();
274+ if (test__start_subtest ("intersect" ))
275+ test_intersect ();
183276}
0 commit comments