summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorAndrii Nakryiko <andrii@kernel.org>2022-10-05 21:24:52 -0700
committerAlexei Starovoitov <ast@kernel.org>2022-10-06 08:19:30 -0700
commitce3e44a09dce74ca68fa56c23333378d936969b0 (patch)
tree178a34cb6db8de0afb364f28f39c027566e83df1 /scripts
parent8a76145a2ec2a81dfe34d7ac42e8c242f095e8c8 (diff)
scripts/bpf_doc.py: update logic to not assume sequential enum values
Relax bpf_doc.py's expectation of all BPF_FUNC_xxx enumerators having sequential values increasing by one. Instead, only make sure that relative order of BPF helper descriptions in comments matches enumerators definitions order. Also additionally make sure that helper IDs are not duplicated. And also make sure that for cases when we have multiple descriptions for the same BPF helper (e.g., for bpf_get_socket_cookie()), all such descriptions are grouped together. Such checks should capture all the same (and more) issues in upstream UAPI headers, but also handle backported kernels correctly. Reported-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Reviewed-by: Quentin Monnet <quentin@isovalent.com> Link: https://lore.kernel.org/r/20221006042452.2089843-2-andrii@kernel.org Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/bpf_doc.py31
1 files changed, 25 insertions, 6 deletions
diff --git a/scripts/bpf_doc.py b/scripts/bpf_doc.py
index 2fe07c9e3fe0..c0e6690be82a 100755
--- a/scripts/bpf_doc.py
+++ b/scripts/bpf_doc.py
@@ -97,6 +97,7 @@ class HeaderParser(object):
self.desc_unique_helpers = set()
self.define_unique_helpers = []
self.helper_enum_vals = {}
+ self.helper_enum_pos = {}
self.desc_syscalls = []
self.enum_syscalls = []
@@ -264,42 +265,60 @@ class HeaderParser(object):
# Searches for one FN(\w+) define or a backslash for newline
p = re.compile('\s*FN\((\w+), (\d+), ##ctx\)|\\\\')
fn_defines_str = ''
+ i = 0
while True:
capture = p.match(self.line)
if capture:
fn_defines_str += self.line
- self.helper_enum_vals[capture.expand(r'bpf_\1')] = int(capture[2])
+ helper_name = capture.expand(r'bpf_\1')
+ self.helper_enum_vals[helper_name] = int(capture[2])
+ self.helper_enum_pos[helper_name] = i
+ i += 1
else:
break
self.line = self.reader.readline()
# Find the number of occurences of FN(\w+)
self.define_unique_helpers = re.findall('FN\(\w+, \d+, ##ctx\)', fn_defines_str)
- def assign_helper_values(self):
+ def validate_helpers(self):
+ last_helper = ''
seen_helpers = set()
+ seen_enum_vals = set()
+ i = 0
for helper in self.helpers:
proto = helper.proto_break_down()
name = proto['name']
try:
enum_val = self.helper_enum_vals[name]
+ enum_pos = self.helper_enum_pos[name]
except KeyError:
raise Exception("Helper %s is missing from enum bpf_func_id" % name)
+ if name in seen_helpers:
+ if last_helper != name:
+ raise Exception("Helper %s has multiple descriptions which are not grouped together" % name)
+ continue
+
# Enforce current practice of having the descriptions ordered
# by enum value.
+ if enum_pos != i:
+ raise Exception("Helper %s (ID %d) comment order (#%d) must be aligned with its position (#%d) in enum bpf_func_id" % (name, enum_val, i + 1, enum_pos + 1))
+ if enum_val in seen_enum_vals:
+ raise Exception("Helper %s has duplicated value %d" % (name, enum_val))
+
seen_helpers.add(name)
- desc_val = len(seen_helpers)
- if desc_val != enum_val:
- raise Exception("Helper %s comment order (#%d) must be aligned with its position (#%d) in enum bpf_func_id" % (name, desc_val, enum_val))
+ last_helper = name
+ seen_enum_vals.add(enum_val)
helper.enum_val = enum_val
+ i += 1
def run(self):
self.parse_desc_syscall()
self.parse_enum_syscall()
self.parse_desc_helpers()
self.parse_define_helpers()
- self.assign_helper_values()
+ self.validate_helpers()
self.reader.close()
###############################################################################