Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next

Alexei Starovoitov says:

====================
pull-request: bpf-next 2021-03-09

The following pull-request contains BPF updates for your *net-next* tree.

We've added 90 non-merge commits during the last 17 day(s) which contain
a total of 114 files changed, 5158 insertions(+), 1288 deletions(-).

The main changes are:

1) Faster bpf_redirect_map(), from Björn.

2) skmsg cleanup, from Cong.

3) Support for floating point types in BTF, from Ilya.

4) Documentation for sys_bpf commands, from Joe.

5) Support for sk_lookup in bpf_prog_test_run, form Lorenz.

6) Enable task local storage for tracing programs, from Song.

7) bpf_for_each_map_elem() helper, from Yonghong.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller
2021-03-09 18:07:05 -08:00
114 changed files with 5158 additions and 1286 deletions

View File

@@ -2,6 +2,7 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# Copyright (C) 2018-2019 Netronome Systems, Inc.
# Copyright (C) 2021 Isovalent, Inc.
# In case user attempts to run with Python 2.
from __future__ import print_function
@@ -13,6 +14,9 @@ import sys, os
class NoHelperFound(BaseException):
pass
class NoSyscallCommandFound(BaseException):
pass
class ParsingError(BaseException):
def __init__(self, line='<line not provided>', reader=None):
if reader:
@@ -22,18 +26,27 @@ class ParsingError(BaseException):
else:
BaseException.__init__(self, 'Error parsing line: %s' % line)
class Helper(object):
class APIElement(object):
"""
An object representing the description of an eBPF helper function.
@proto: function prototype of the helper function
@desc: textual description of the helper function
@ret: description of the return value of the helper function
An object representing the description of an aspect of the eBPF API.
@proto: prototype of the API symbol
@desc: textual description of the symbol
@ret: (optional) description of any associated return value
"""
def __init__(self, proto='', desc='', ret=''):
self.proto = proto
self.desc = desc
self.ret = ret
class Helper(APIElement):
"""
An object representing the description of an eBPF helper function.
@proto: function prototype of the helper function
@desc: textual description of the helper function
@ret: description of the return value of the helper function
"""
def proto_break_down(self):
"""
Break down helper function protocol into smaller chunks: return type,
@@ -60,6 +73,7 @@ class Helper(object):
return res
class HeaderParser(object):
"""
An object used to parse a file in order to extract the documentation of a
@@ -72,6 +86,13 @@ class HeaderParser(object):
self.reader = open(filename, 'r')
self.line = ''
self.helpers = []
self.commands = []
def parse_element(self):
proto = self.parse_symbol()
desc = self.parse_desc()
ret = self.parse_ret()
return APIElement(proto=proto, desc=desc, ret=ret)
def parse_helper(self):
proto = self.parse_proto()
@@ -79,6 +100,18 @@ class HeaderParser(object):
ret = self.parse_ret()
return Helper(proto=proto, desc=desc, ret=ret)
def parse_symbol(self):
p = re.compile(' \* ?(.+)$')
capture = p.match(self.line)
if not capture:
raise NoSyscallCommandFound
end_re = re.compile(' \* ?NOTES$')
end = end_re.match(self.line)
if end:
raise NoSyscallCommandFound
self.line = self.reader.readline()
return capture.group(1)
def parse_proto(self):
# Argument can be of shape:
# - "void"
@@ -140,16 +173,29 @@ class HeaderParser(object):
break
return ret
def run(self):
# Advance to start of helper function descriptions.
offset = self.reader.read().find('* Start of BPF helper function descriptions:')
def seek_to(self, target, help_message):
self.reader.seek(0)
offset = self.reader.read().find(target)
if offset == -1:
raise Exception('Could not find start of eBPF helper descriptions list')
raise Exception(help_message)
self.reader.seek(offset)
self.reader.readline()
self.reader.readline()
self.line = self.reader.readline()
def parse_syscall(self):
self.seek_to('* DOC: eBPF Syscall Commands',
'Could not find start of eBPF syscall descriptions list')
while True:
try:
command = self.parse_element()
self.commands.append(command)
except NoSyscallCommandFound:
break
def parse_helpers(self):
self.seek_to('* Start of BPF helper function descriptions:',
'Could not find start of eBPF helper descriptions list')
while True:
try:
helper = self.parse_helper()
@@ -157,6 +203,9 @@ class HeaderParser(object):
except NoHelperFound:
break
def run(self):
self.parse_syscall()
self.parse_helpers()
self.reader.close()
###############################################################################
@@ -165,10 +214,11 @@ class Printer(object):
"""
A generic class for printers. Printers should be created with an array of
Helper objects, and implement a way to print them in the desired fashion.
@helpers: array of Helper objects to print to standard output
@parser: A HeaderParser with objects to print to standard output
"""
def __init__(self, helpers):
self.helpers = helpers
def __init__(self, parser):
self.parser = parser
self.elements = []
def print_header(self):
pass
@@ -181,19 +231,23 @@ class Printer(object):
def print_all(self):
self.print_header()
for helper in self.helpers:
self.print_one(helper)
for elem in self.elements:
self.print_one(elem)
self.print_footer()
class PrinterRST(Printer):
"""
A printer for dumping collected information about helpers as a ReStructured
Text page compatible with the rst2man program, which can be used to
generate a manual page for the helpers.
@helpers: array of Helper objects to print to standard output
A generic class for printers that print ReStructured Text. Printers should
be created with a HeaderParser object, and implement a way to print API
elements in the desired fashion.
@parser: A HeaderParser with objects to print to standard output
"""
def print_header(self):
header = '''\
def __init__(self, parser):
self.parser = parser
def print_license(self):
license = '''\
.. Copyright (C) All BPF authors and contributors from 2014 to present.
.. See git log include/uapi/linux/bpf.h in kernel tree for details.
..
@@ -221,9 +275,39 @@ class PrinterRST(Printer):
..
.. Please do not edit this file. It was generated from the documentation
.. located in file include/uapi/linux/bpf.h of the Linux kernel sources
.. (helpers description), and from scripts/bpf_helpers_doc.py in the same
.. (helpers description), and from scripts/bpf_doc.py in the same
.. repository (header and footer).
'''
print(license)
def print_elem(self, elem):
if (elem.desc):
print('\tDescription')
# Do not strip all newline characters: formatted code at the end of
# a section must be followed by a blank line.
for line in re.sub('\n$', '', elem.desc, count=1).split('\n'):
print('{}{}'.format('\t\t' if line else '', line))
if (elem.ret):
print('\tReturn')
for line in elem.ret.rstrip().split('\n'):
print('{}{}'.format('\t\t' if line else '', line))
print('')
class PrinterHelpersRST(PrinterRST):
"""
A printer for dumping collected information about helpers as a ReStructured
Text page compatible with the rst2man program, which can be used to
generate a manual page for the helpers.
@parser: A HeaderParser with Helper objects to print to standard output
"""
def __init__(self, parser):
self.elements = parser.helpers
def print_header(self):
header = '''\
===========
BPF-HELPERS
===========
@@ -264,6 +348,7 @@ kernel at the top).
HELPERS
=======
'''
PrinterRST.print_license(self)
print(header)
def print_footer(self):
@@ -380,27 +465,50 @@ SEE ALSO
def print_one(self, helper):
self.print_proto(helper)
self.print_elem(helper)
if (helper.desc):
print('\tDescription')
# Do not strip all newline characters: formatted code at the end of
# a section must be followed by a blank line.
for line in re.sub('\n$', '', helper.desc, count=1).split('\n'):
print('{}{}'.format('\t\t' if line else '', line))
if (helper.ret):
print('\tReturn')
for line in helper.ret.rstrip().split('\n'):
print('{}{}'.format('\t\t' if line else '', line))
class PrinterSyscallRST(PrinterRST):
"""
A printer for dumping collected information about the syscall API as a
ReStructured Text page compatible with the rst2man program, which can be
used to generate a manual page for the syscall.
@parser: A HeaderParser with APIElement objects to print to standard
output
"""
def __init__(self, parser):
self.elements = parser.commands
def print_header(self):
header = '''\
===
bpf
===
-------------------------------------------------------------------------------
Perform a command on an extended BPF object
-------------------------------------------------------------------------------
:Manual section: 2
COMMANDS
========
'''
PrinterRST.print_license(self)
print(header)
def print_one(self, command):
print('**%s**' % (command.proto))
self.print_elem(command)
print('')
class PrinterHelpers(Printer):
"""
A printer for dumping collected information about helpers as C header to
be included from BPF program.
@helpers: array of Helper objects to print to standard output
@parser: A HeaderParser with Helper objects to print to standard output
"""
def __init__(self, parser):
self.elements = parser.helpers
type_fwds = [
'struct bpf_fib_lookup',
@@ -511,7 +619,7 @@ class PrinterHelpers(Printer):
def print_header(self):
header = '''\
/* This is auto-generated file. See bpf_helpers_doc.py for details. */
/* This is auto-generated file. See bpf_doc.py for details. */
/* Forward declarations of BPF structs */'''
@@ -589,8 +697,13 @@ script = os.path.abspath(sys.argv[0])
linuxRoot = os.path.dirname(os.path.dirname(script))
bpfh = os.path.join(linuxRoot, 'include/uapi/linux/bpf.h')
printers = {
'helpers': PrinterHelpersRST,
'syscall': PrinterSyscallRST,
}
argParser = argparse.ArgumentParser(description="""
Parse eBPF header file and generate documentation for eBPF helper functions.
Parse eBPF header file and generate documentation for the eBPF API.
The RST-formatted output produced can be turned into a manual page with the
rst2man utility.
""")
@@ -601,6 +714,8 @@ if (os.path.isfile(bpfh)):
default=bpfh)
else:
argParser.add_argument('--filename', help='path to include/uapi/linux/bpf.h')
argParser.add_argument('target', nargs='?', default='helpers',
choices=printers.keys(), help='eBPF API target')
args = argParser.parse_args()
# Parse file.
@@ -609,7 +724,9 @@ headerParser.run()
# Print formatted output to standard output.
if args.header:
printer = PrinterHelpers(headerParser.helpers)
if args.target != 'helpers':
raise NotImplementedError('Only helpers header generation is supported')
printer = PrinterHelpers(headerParser)
else:
printer = PrinterRST(headerParser.helpers)
printer = printers[args.target](headerParser)
printer.print_all()