netlink: specs: support conditional operations

Page pool code is compiled conditionally, but the operations
are part of the shared netlink family. We can handle this
by reporting empty list of pools or -EOPNOTSUPP / -ENOSYS
but the cleanest way seems to be removing the ops completely
at compilation time. That way user can see that the page
pool ops are not present using genetlink introspection.
Same way they'd check if the kernel is "new enough" to
support the ops.

Extend the specs with the ability to specify the config
condition under which op (and its policies, etc.) should
be hidden.

Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Link: https://lore.kernel.org/r/20231025162253.133159-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2023-10-25 09:22:53 -07:00
parent ea23fbd2a8
commit bc30bb88ff
4 changed files with 37 additions and 0 deletions

View File

@ -295,6 +295,11 @@ properties:
type: array
items:
enum: [ strict, dump, dump-strict ]
config-cond:
description: |
Name of the kernel config option gating the presence of
the operation, without the 'CONFIG_' prefix.
type: string
do: &subop-type
description: Main command handler.
type: object

View File

@ -346,6 +346,11 @@ properties:
type: array
items:
enum: [ strict, dump, dump-strict ]
config-cond:
description: |
Name of the kernel config option gating the presence of
the operation, without the 'CONFIG_' prefix.
type: string
# Start genetlink-legacy
fixed-header: *fixed-header
# End genetlink-legacy

View File

@ -264,6 +264,11 @@ properties:
type: array
items:
enum: [ strict, dump, dump-strict ]
config-cond:
description: |
Name of the kernel config option gating the presence of
the operation, without the 'CONFIG_' prefix.
type: string
do: &subop-type
description: Main command handler.
type: object

View File

@ -1162,6 +1162,7 @@ class CodeWriter:
self._block_end = False
self._silent_block = False
self._ind = 0
self._ifdef_block = None
if out_file is None:
self._out = os.sys.stdout
else:
@ -1202,6 +1203,8 @@ class CodeWriter:
if self._silent_block:
ind += 1
self._silent_block = line.endswith(')') and CodeWriter._is_cond(line)
if line[0] == '#':
ind = 0
if add_ind:
ind += add_ind
self._out.write('\t' * ind + line + '\n')
@ -1328,6 +1331,19 @@ class CodeWriter:
line += '= ' + str(one[1]) + ','
self.p(line)
def ifdef_block(self, config):
config_option = None
if config:
config_option = 'CONFIG_' + c_upper(config)
if self._ifdef_block == config_option:
return
if self._ifdef_block:
self.p('#endif /* ' + self._ifdef_block + ' */')
if config_option:
self.p('#ifdef ' + config_option)
self._ifdef_block = config_option
scalars = {'u8', 'u16', 'u32', 'u64', 's32', 's64', 'uint', 'sint'}
@ -2006,10 +2022,13 @@ def print_req_policy_fwd(cw, struct, ri=None, terminate=True):
def print_req_policy(cw, struct, ri=None):
if ri and ri.op:
cw.ifdef_block(ri.op.get('config-cond', None))
print_req_policy_fwd(cw, struct, ri=ri, terminate=False)
for _, arg in struct.member_list():
arg.attr_policy(cw)
cw.p("};")
cw.ifdef_block(None)
cw.nl()
@ -2127,6 +2146,7 @@ def print_kernel_op_table(family, cw):
if op.is_async:
continue
cw.ifdef_block(op.get('config-cond', None))
cw.block_start()
members = [('cmd', op.enum_name)]
if 'dont-validate' in op:
@ -2157,6 +2177,7 @@ def print_kernel_op_table(family, cw):
if op.is_async or op_mode not in op:
continue
cw.ifdef_block(op.get('config-cond', None))
cw.block_start()
members = [('cmd', op.enum_name)]
if 'dont-validate' in op:
@ -2192,6 +2213,7 @@ def print_kernel_op_table(family, cw):
members.append(('flags', ' | '.join([c_upper('genl-' + x) for x in flags])))
cw.write_struct_init(members)
cw.block_end(line=',')
cw.ifdef_block(None)
cw.block_end(line=';')
cw.nl()