selftests/bpf: Add uprobe sessions to consumer test

Adding uprobe session consumers to the consumer test,
so we get the session into the test mix.

In addition scaling down the test to have just 1 uprobe
and 1 uretprobe, otherwise the test time grows and is
unsuitable for CI even with threads.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20241108134544.480660-13-jolsa@kernel.org
This commit is contained in:
Jiri Olsa 2024-11-08 14:45:43 +01:00 committed by Andrii Nakryiko
parent c574bcd622
commit b1c570adc7
2 changed files with 52 additions and 24 deletions

View File

@ -799,10 +799,13 @@ static int uprobe_attach(struct uprobe_multi_consumers *skel, int idx)
return -1;
/*
* bit/prog: 0,1 uprobe entry
* bit/prog: 2,3 uprobe return
* bit/prog: 0 uprobe entry
* bit/prog: 1 uprobe return
* bit/prog: 2 uprobe session without return
* bit/prog: 3 uprobe session with return
*/
opts.retprobe = idx == 2 || idx == 3;
opts.retprobe = idx == 1;
opts.session = idx == 2 || idx == 3;
*link = bpf_program__attach_uprobe_multi(prog, 0, "/proc/self/exe",
"uprobe_consumer_test",
@ -867,31 +870,55 @@ static int consumer_test(struct uprobe_multi_consumers *skel,
goto cleanup;
for (idx = 0; idx < 4; idx++) {
bool uret_stays, uret_survives;
const char *fmt = "BUG";
__u64 val = 0;
if (idx < 2) {
switch (idx) {
case 0:
/*
* uprobe entry
* +1 if define in 'before'
*/
if (test_bit(idx, before))
val++;
fmt = "prog 0/1: uprobe";
} else {
fmt = "prog 0: uprobe";
break;
case 1:
/*
* To trigger uretprobe consumer, the uretprobe under test either stayed from
* before to after (uret_stays + test_bit) or uretprobe instance survived and
* we have uretprobe active in after (uret_survives + test_bit)
*/
bool uret_stays = before & after & 0b1100;
bool uret_survives = (before & 0b1100) && (after & 0b1100) && (before & 0b0011);
uret_stays = before & after & 0b0110;
uret_survives = ((before & 0b0110) && (after & 0b0110) && (before & 0b1001));
if ((uret_stays || uret_survives) && test_bit(idx, after))
val++;
fmt = "idx 2/3: uretprobe";
fmt = "prog 1: uretprobe";
break;
case 2:
/*
* session with return
* +1 if defined in 'before'
* +1 if defined in 'after'
*/
if (test_bit(idx, before)) {
val++;
if (test_bit(idx, after))
val++;
}
fmt = "prog 2: session with return";
break;
case 3:
/*
* session without return
* +1 if defined in 'before'
*/
if (test_bit(idx, before))
val++;
fmt = "prog 3: session with NO return";
break;
}
if (!ASSERT_EQ(skel->bss->uprobe_result[idx], val, fmt))
@ -920,8 +947,10 @@ static void test_consumers(void)
* The idea of this test is to try all possible combinations of
* uprobes consumers attached on single function.
*
* - 2 uprobe entry consumer
* - 2 uprobe exit consumers
* - 1 uprobe entry consumer
* - 1 uprobe exit consumer
* - 1 uprobe session with return
* - 1 uprobe session without return
*
* The test uses 4 uprobes attached on single function, but that
* translates into single uprobe with 4 consumers in kernel.
@ -929,25 +958,24 @@ static void test_consumers(void)
* The before/after values present the state of attached consumers
* before and after the probed function:
*
* bit/prog 0,1 : uprobe entry
* bit/prog 2,3 : uprobe return
* bit/prog 0 : uprobe entry
* bit/prog 1 : uprobe return
*
* For example for:
*
* before = 0b0101
* after = 0b0110
* before = 0b01
* after = 0b10
*
* it means that before we call 'uprobe_consumer_test' we attach
* uprobes defined in 'before' value:
*
* - bit/prog 0: uprobe entry
* - bit/prog 2: uprobe return
* - bit/prog 1: uprobe entry
*
* uprobe_consumer_test is called and inside it we attach and detach
* uprobes based on 'after' value:
*
* - bit/prog 0: stays untouched
* - bit/prog 2: uprobe return is detached
* - bit/prog 0: is detached
* - bit/prog 1: is attached
*
* uprobe_consumer_test returns and we check counters values increased
* by bpf programs on each uprobe to match the expected count based on

View File

@ -24,16 +24,16 @@ int uprobe_1(struct pt_regs *ctx)
return 0;
}
SEC("uprobe.multi")
SEC("uprobe.session")
int uprobe_2(struct pt_regs *ctx)
{
uprobe_result[2]++;
return 0;
}
SEC("uprobe.multi")
SEC("uprobe.session")
int uprobe_3(struct pt_regs *ctx)
{
uprobe_result[3]++;
return 0;
return 1;
}