Re: Question about pointer to forward type

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On 11/3/2021 11:58 AM, Yonghong Song wrote:
>
>
> On 10/15/21 7:22 AM, Hou Tao wrote:
>> Hi,
>>
>> When adding test case for BPF STRUCT OPS, I got the following error
>> during test:
>>
>> libbpf: load bpf program failed: Permission denied
>> libbpf: -- BEGIN DUMP LOG ---
>> libbpf:
>> R1 type=ctx expected=fp
>> ; int BPF_PROG(test_1, struct bpf_dummy_ops_state *state)
>> 0: (b4) w0 = -218893067
>> ; int BPF_PROG(test_1, struct bpf_dummy_ops_state *state)
>> 1: (79) r1 = *(u64 *)(r1 +0)
>> func 'test_1' arg0 type FWD is not a struct
>> invalid bpf_context access off=0 size=8
>>
>> The error is reported from btf_ctx_access(). And the cause is
>> the definition of struct bpf_dummy_ops_state is separated from
>> the definition of test_1 function:
>>
>> test_1 is defined in include/linux/bpf.h
>>
>> struct bpf_dummy_ops_state;
>> struct bpf_dummy_ops {
>>          int (*test_1)(struct bpf_dummy_ops_state *cb);
>> }
>>
>> bpf_dummy_ops_state is defined in net/bpf/bpf_dummy_struct_ops.c
>>
>> struct bpf_dummy_ops_state {
>> };
>>
>> So arg0 has BTF_KIND_FWD type, and the check in btf_ctx_access() fails.
>> The problem can be fixed by moving the definition of bpf_dummy_ops_state
>> into include/linux/bpf.h or using a void * instead of
>> struct bpf_dummy_ops_state *. But forward declaration is possible under
>> STRUCT_OPS scenario, so my question is whether or not it is a known issue
>> and is there somebody working on this ?
>
> I suspect this is what happened.
> The 'struct bpf_dummy_ops_state' is defined in net/bpf/bpf_dummy_struct_ops.c,
> but this structure is not used in that file
> so there is no definition in the bpf_dummy_struct_ops.o dwarf.
>
> Since in the final combined dwarf, there is no "struct bpf_dummy_ops_state"
> definition, dedup won't be able to replace
> forward declaration with actual definition. And this caused
> your above issue.
>
> It would be good if you can verifier whether this is the case or
> not. If bpf_dummy_ops_state definition is in the dwarf, then we
> likely have a dedup problem.
struct bpf_dummy_ops_state is used in net/bpf/bpf_dummy_struct_ops.c, but
the problem still exists.

And it can be reproduced by moving the definition of bpf_dummy_ops_state
from include/linux/bpf.h to bpf_dummy_struct_ops.c as shown below and
running "./test_progs -t dummy_st_ops":

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 2be6dfd68df9..1d1e6dff5ce8 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -1024,9 +1024,7 @@ static inline void bpf_module_put(const void *data, struct
module *owner)

 #ifdef CONFIG_NET
 /* Define it here to avoid the use of forward declaration */
-struct bpf_dummy_ops_state {
-       int val;
-};
+struct bpf_dummy_ops_state;

 struct bpf_dummy_ops {
        int (*test_1)(struct bpf_dummy_ops_state *cb);
diff --git a/net/bpf/bpf_dummy_struct_ops.c b/net/bpf/bpf_dummy_struct_ops.c
index fbc896323bec..2beb755b5806 100644
--- a/net/bpf/bpf_dummy_struct_ops.c
+++ b/net/bpf/bpf_dummy_struct_ops.c
@@ -9,6 +9,10 @@

 extern struct bpf_struct_ops bpf_bpf_dummy_ops;

+struct bpf_dummy_ops_state {
+       int val;
+};
+
 /* A common type for test_N with return value in bpf_dummy_ops */
 typedef int (*dummy_ops_test_ret_fn)(struct bpf_dummy_ops_state *state, ...);


The following is the output of vmliux btf dump. We can see that it does
have the definition of bpf_dummy_ops_state.

# bpftool btf dump id 1 | grep "test_1\|bpf_dummy_ops_state" -A 6 -B 1
[29190] STRUCT 'bpf_dummy_ops' size=16 vlen=2
        'test_1' type_id=29194 bits_offset=0
        'test_2' type_id=29196 bits_offset=64
[29191] FUNC_PROTO '(anon)' ret_type_id=21 vlen=1
        '(anon)' type_id=29192
[29192] PTR '(anon)' type_id=29193
[29193] FWD 'bpf_dummy_ops_state' fwd_kind=struct
[29194] PTR '(anon)' type_id=29191

--
[106565] STRUCT 'bpf_dummy_ops_state' size=4 vlen=1
        'val' type_id=21 bits_offset=0
[106566] TYPEDEF 'dummy_ops_test_ret_fn' type_id=106567
[106567] PTR '(anon)' type_id=106568

And the definition of bpf_dummy_ops_state comes from
bpf_dummy_struct_ops.o:

# pahole -JV build/net/bpf/bpf_dummy_struct_ops.o | grep bpf_dummy_ops_state
[1910] STRUCT bpf_dummy_ops_state size=4

>
>>
>> Regards,
>> Tao
>>
> .




[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux