From a8a9fd042e0995ed63d33f507c26baf56031e581 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Wed, 23 Jul 2025 10:10:42 -0700 Subject: tools: ynl-gen: don't add suffix for pure types Don't add _req to helper names for pure types. We don't currently print those so it makes no difference to existing codegen. Reviewed-by: Donald Hunter Acked-by: Stanislav Fomichev Link: https://patch.msgid.link/20250723171046.4027470-2-kuba@kernel.org Signed-off-by: Jakub Kicinski --- tools/net/ynl/pyynl/ynl_gen_c.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tools/net/ynl/pyynl/ynl_gen_c.py') diff --git a/tools/net/ynl/pyynl/ynl_gen_c.py b/tools/net/ynl/pyynl/ynl_gen_c.py index 76032e01c2e7..1bdcc368e776 100755 --- a/tools/net/ynl/pyynl/ynl_gen_c.py +++ b/tools/net/ynl/pyynl/ynl_gen_c.py @@ -1879,7 +1879,9 @@ def rdir(direction): def op_prefix(ri, direction, deref=False): suffix = f"_{ri.type_name}" - if not ri.op_mode or ri.op_mode == 'do': + if not ri.op_mode: + pass + elif ri.op_mode == 'do': suffix += f"{direction_to_suffix[direction]}" else: if direction == 'request': -- cgit v1.2.3 From cf5869977702b1d51e3b4d58b6c559a98a366114 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Wed, 23 Jul 2025 10:10:43 -0700 Subject: tools: ynl-gen: move free printing to the print_type_full() helper Just to avoid making the main function even more enormous, before adding more things to print move the free printing to a helper which already prints the type. Reviewed-by: Donald Hunter Acked-by: Stanislav Fomichev Link: https://patch.msgid.link/20250723171046.4027470-3-kuba@kernel.org Signed-off-by: Jakub Kicinski --- tools/net/ynl/pyynl/ynl_gen_c.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'tools/net/ynl/pyynl/ynl_gen_c.py') diff --git a/tools/net/ynl/pyynl/ynl_gen_c.py b/tools/net/ynl/pyynl/ynl_gen_c.py index 1bdcc368e776..dc78542e6c88 100755 --- a/tools/net/ynl/pyynl/ynl_gen_c.py +++ b/tools/net/ynl/pyynl/ynl_gen_c.py @@ -2546,6 +2546,10 @@ def print_type(ri, direction): def print_type_full(ri, struct): _print_type(ri, "", struct) + if struct.request and struct.in_multi_val: + free_rsp_nested_prototype(ri) + ri.cw.nl() + def print_type_helpers(ri, direction, deref=False): print_free_prototype(ri, direction) @@ -3517,9 +3521,6 @@ def main(): for attr_set, struct in parsed.pure_nested_structs.items(): ri = RenderInfo(cw, parsed, args.mode, "", "", attr_set) print_type_full(ri, struct) - if struct.request and struct.in_multi_val: - free_rsp_nested_prototype(ri) - cw.nl() for op_name, op in parsed.ops.items(): cw.p(f"/* ============== {op.enum_name} ============== */") -- cgit v1.2.3 From 2c222dde61c4fcb8693d31acf5ef8e342fda4c26 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Wed, 23 Jul 2025 10:10:44 -0700 Subject: tools: ynl-gen: print alloc helper for multi-val attrs In general YNL provides allocation and free helpers for types. For pure nested structs which are used as multi-attr (and therefore have to be allocated dynamically) we already print a free helper as it's needed by free of the containing struct. Add printing of the alloc helper for consistency. The helper takes the number of entries to allocate as an argument, e.g.: static inline struct netdev_queue_id *netdev_queue_id_alloc(unsigned int n) { return calloc(n, sizeof(struct netdev_queue_id)); } Reviewed-by: Donald Hunter Acked-by: Stanislav Fomichev Link: https://patch.msgid.link/20250723171046.4027470-4-kuba@kernel.org Signed-off-by: Jakub Kicinski --- tools/net/ynl/pyynl/ynl_gen_c.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'tools/net/ynl/pyynl/ynl_gen_c.py') diff --git a/tools/net/ynl/pyynl/ynl_gen_c.py b/tools/net/ynl/pyynl/ynl_gen_c.py index dc78542e6c88..6bc0782f2658 100755 --- a/tools/net/ynl/pyynl/ynl_gen_c.py +++ b/tools/net/ynl/pyynl/ynl_gen_c.py @@ -2472,11 +2472,22 @@ def free_arg_name(direction): return 'obj' -def print_alloc_wrapper(ri, direction): +def print_alloc_wrapper(ri, direction, struct=None): name = op_prefix(ri, direction) - ri.cw.write_func_prot(f'static inline struct {name} *', f"{name}_alloc", [f"void"]) + struct_name = name + if ri.type_name_conflict: + struct_name += '_' + + args = ["void"] + cnt = "1" + if struct and struct.in_multi_val: + args = ["unsigned int n"] + cnt = "n" + + ri.cw.write_func_prot(f'static inline struct {struct_name} *', + f"{name}_alloc", args) ri.cw.block_start() - ri.cw.p(f'return calloc(1, sizeof(struct {name}));') + ri.cw.p(f'return calloc({cnt}, sizeof(struct {struct_name}));') ri.cw.block_end() @@ -2547,6 +2558,8 @@ def print_type_full(ri, struct): _print_type(ri, "", struct) if struct.request and struct.in_multi_val: + print_alloc_wrapper(ri, "", struct) + ri.cw.nl() free_rsp_nested_prototype(ri) ri.cw.nl() -- cgit v1.2.3 From 8553fb7c555c15f32ebbc5d032f35589e970e206 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Wed, 23 Jul 2025 10:10:45 -0700 Subject: tools: ynl-gen: print setters for multi-val attrs For basic types we "flatten" setters. If a request "a" has a simple nest "b" with value "val" we print helpers like: req_set_a_b(struct a *req, int val) { req->_present.a = 1; req->b._present.val = 1; req->b.val = ... } This is not possible for multi-attr because they have to be allocated dynamically by the user. Print "object level" setters so that user preparing the object doesn't have to futz with the presence bits and other YNL internals. Add the ability to pass in the variable name to generated setters. Using "req" here doesn't feel right, while the attr is part of a request it's not the request itself, so it seems cleaner to call it "obj". Example: static inline void netdev_queue_id_set_id(struct netdev_queue_id *obj, __u32 id) { obj->_present.id = 1; obj->id = id; } Reviewed-by: Donald Hunter Acked-by: Stanislav Fomichev Link: https://patch.msgid.link/20250723171046.4027470-5-kuba@kernel.org Signed-off-by: Jakub Kicinski --- tools/net/ynl/pyynl/ynl_gen_c.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'tools/net/ynl/pyynl/ynl_gen_c.py') diff --git a/tools/net/ynl/pyynl/ynl_gen_c.py b/tools/net/ynl/pyynl/ynl_gen_c.py index 6bc0782f2658..ef032e17fec4 100755 --- a/tools/net/ynl/pyynl/ynl_gen_c.py +++ b/tools/net/ynl/pyynl/ynl_gen_c.py @@ -275,9 +275,8 @@ class Type(SpecAttr): def _setter_lines(self, ri, member, presence): raise Exception(f"Setter not implemented for class type {self.type}") - def setter(self, ri, space, direction, deref=False, ref=None): + def setter(self, ri, space, direction, deref=False, ref=None, var="req"): ref = (ref if ref else []) + [self.c_name] - var = "req" member = f"{var}->{'.'.join(ref)}" local_vars = [] @@ -332,7 +331,7 @@ class TypeUnused(Type): def attr_get(self, ri, var, first): pass - def setter(self, ri, space, direction, deref=False, ref=None): + def setter(self, ri, space, direction, deref=False, ref=None, var=None): pass @@ -355,7 +354,7 @@ class TypePad(Type): def attr_policy(self, cw): pass - def setter(self, ri, space, direction, deref=False, ref=None): + def setter(self, ri, space, direction, deref=False, ref=None, var=None): pass @@ -695,13 +694,14 @@ class TypeNest(Type): f"parg.data = &{var}->{self.c_name};"] return get_lines, init_lines, None - def setter(self, ri, space, direction, deref=False, ref=None): + def setter(self, ri, space, direction, deref=False, ref=None, var="req"): ref = (ref if ref else []) + [self.c_name] for _, attr in ri.family.pure_nested_structs[self.nested_attrs].member_list(): if attr.is_recursive(): continue - attr.setter(ri, self.nested_attrs, direction, deref=deref, ref=ref) + attr.setter(ri, self.nested_attrs, direction, deref=deref, ref=ref, + var=var) class TypeMultiAttr(Type): @@ -2563,6 +2563,13 @@ def print_type_full(ri, struct): free_rsp_nested_prototype(ri) ri.cw.nl() + # Name conflicts are too hard to deal with with the current code base, + # they are very rare so don't bother printing setters in that case. + if ri.ku_space == 'user' and not ri.type_name_conflict: + for _, attr in struct.member_list(): + attr.setter(ri, ri.attr_set, "", var="obj") + ri.cw.nl() + def print_type_helpers(ri, direction, deref=False): print_free_prototype(ri, direction) -- cgit v1.2.3