Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

xdrgen: Emit a max_arg_sz macro

struct svc_service has a .vs_xdrsize field that is filled in by
servers for each of their RPC programs. This field is supposed to
contain the size of the largest procedure argument in the RPC
program. This value is also sometimes used to size network
transport buffers.

Currently, server implementations must manually calculate and
hard-code this value, which is error-prone and requires updates
when procedure arguments change.

Update xdrgen to determine which procedure argument structure is
largest, and emit a macro with a well-known name that contains
the size of that structure. Server code then uses this macro when
initializing the .vs_xdrsize field.

For NLM version 4, xdrgen now emits:

#define NLM4_MAX_ARGS_SZ (NLM4_nlm4_lockargs_sz)

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>

+39 -1
+34 -1
tools/net/sunrpc/xdrgen/generators/program.py
··· 5 5 6 6 from jinja2 import Environment 7 7 8 - from generators import SourceGenerator, create_jinja2_environment 8 + from generators import SourceGenerator, create_jinja2_environment, get_jinja2_template 9 9 from xdr_ast import _RpcProgram, _RpcVersion, excluded_apis 10 + from xdr_ast import max_widths, get_header_name 10 11 11 12 12 13 def emit_version_definitions( ··· 170 169 emit_version_argument_encoders( 171 170 self.environment, program, version, 172 171 ) 172 + 173 + def emit_maxsize(self, node: _RpcProgram) -> None: 174 + """Emit maxsize macro for maximum RPC argument size""" 175 + header = get_header_name().upper() 176 + 177 + # Find the largest argument across all versions 178 + max_arg_width = 0 179 + max_arg_name = None 180 + for version in node.versions: 181 + for procedure in version.procedures: 182 + if procedure.name in excluded_apis: 183 + continue 184 + arg_name = procedure.argument.type_name 185 + if arg_name == "void": 186 + continue 187 + if arg_name not in max_widths: 188 + continue 189 + if max_widths[arg_name] > max_arg_width: 190 + max_arg_width = max_widths[arg_name] 191 + max_arg_name = arg_name 192 + 193 + if max_arg_name is None: 194 + return 195 + 196 + macro_name = header + "_MAX_ARGS_SZ" 197 + template = get_jinja2_template(self.environment, "maxsize", "max_args") 198 + print( 199 + template.render( 200 + macro=macro_name, 201 + width=header + "_" + max_arg_name + "_sz", 202 + ) 203 + )
+2
tools/net/sunrpc/xdrgen/subcmds/definitions.py
··· 66 66 gen = XdrStructGenerator(language, peer) 67 67 elif isinstance(definition.value, _XdrUnion): 68 68 gen = XdrUnionGenerator(language, peer) 69 + elif isinstance(definition.value, _RpcProgram): 70 + gen = XdrProgramGenerator(language, peer) 69 71 else: 70 72 continue 71 73 gen.emit_maxsize(definition.value)
+3
tools/net/sunrpc/xdrgen/templates/C/program/maxsize/max_args.j2
··· 1 + {# SPDX-License-Identifier: GPL-2.0 #} 2 + #define {{ '{:<31}'.format(macro) }} \ 3 + ({{ width }})