Skip to content

Commit c911fc6

Browse files
ThinkerYzu1anakryiko
authored andcommitted
libbpf: Skip zeroed or null fields if not found in the kernel type.
Accept additional fields of a struct_ops type with all zero values even if these fields are not in the corresponding type in the kernel. This provides a way to be backward compatible. User space programs can use the same map on a machine running an old kernel by clearing fields that do not exist in the kernel. Signed-off-by: Kui-Feng Lee <[email protected]> Signed-off-by: Andrii Nakryiko <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent 9bf48fa commit c911fc6

File tree

1 file changed

+19
-5
lines changed

1 file changed

+19
-5
lines changed

tools/lib/bpf/libbpf.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,8 +1132,26 @@ static int bpf_map__init_kern_struct_ops(struct bpf_map *map)
11321132
const char *mname;
11331133

11341134
mname = btf__name_by_offset(btf, member->name_off);
1135+
moff = member->offset / 8;
1136+
mdata = data + moff;
1137+
msize = btf__resolve_size(btf, member->type);
1138+
if (msize < 0) {
1139+
pr_warn("struct_ops init_kern %s: failed to resolve the size of member %s\n",
1140+
map->name, mname);
1141+
return msize;
1142+
}
1143+
11351144
kern_member = find_member_by_name(kern_btf, kern_type, mname);
11361145
if (!kern_member) {
1146+
/* Skip all zeros or null fields if they are not
1147+
* presented in the kernel BTF.
1148+
*/
1149+
if (libbpf_is_mem_zeroed(mdata, msize)) {
1150+
pr_info("struct_ops %s: member %s not found in kernel, skipping it as it's set to zero\n",
1151+
map->name, mname);
1152+
continue;
1153+
}
1154+
11371155
pr_warn("struct_ops init_kern %s: Cannot find member %s in kernel BTF\n",
11381156
map->name, mname);
11391157
return -ENOTSUP;
@@ -1147,10 +1165,7 @@ static int bpf_map__init_kern_struct_ops(struct bpf_map *map)
11471165
return -ENOTSUP;
11481166
}
11491167

1150-
moff = member->offset / 8;
11511168
kern_moff = kern_member->offset / 8;
1152-
1153-
mdata = data + moff;
11541169
kern_mdata = kern_data + kern_moff;
11551170

11561171
mtype = skip_mods_and_typedefs(btf, member->type, &mtype_id);
@@ -1230,9 +1245,8 @@ static int bpf_map__init_kern_struct_ops(struct bpf_map *map)
12301245
continue;
12311246
}
12321247

1233-
msize = btf__resolve_size(btf, mtype_id);
12341248
kern_msize = btf__resolve_size(kern_btf, kern_mtype_id);
1235-
if (msize < 0 || kern_msize < 0 || msize != kern_msize) {
1249+
if (kern_msize < 0 || msize != kern_msize) {
12361250
pr_warn("struct_ops init_kern %s: Error in size of member %s: %zd != %zd(kernel)\n",
12371251
map->name, mname, (ssize_t)msize,
12381252
(ssize_t)kern_msize);

0 commit comments

Comments
 (0)