]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
drop some tools-ynl patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 24 Apr 2025 10:31:07 +0000 (12:31 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 24 Apr 2025 10:31:07 +0000 (12:31 +0200)
12 files changed:
queue-6.12/series
queue-6.12/tools-ynl-gen-individually-free-previous-values-on-d.patch [deleted file]
queue-6.12/tools-ynl-gen-make-sure-we-validate-subtype-of-array.patch [deleted file]
queue-6.14/series
queue-6.14/tools-ynl-gen-individually-free-previous-values-on-d.patch [deleted file]
queue-6.14/tools-ynl-gen-make-sure-we-validate-subtype-of-array.patch [deleted file]
queue-6.6/series
queue-6.6/tools-ynl-gen-individually-free-previous-values-on-d.patch [deleted file]
queue-6.6/tools-ynl-gen-re-sort-ignoring-recursive-nests.patch [deleted file]
queue-6.6/tools-ynl-gen-record-information-about-recursive-nes.patch [deleted file]
queue-6.6/tools-ynl-gen-store-recursive-nests-by-a-pointer.patch [deleted file]
queue-6.6/tools-ynl-gen-track-attribute-use.patch [deleted file]

index c249b1be1d074900dbfc88512bd5b70f176f6e5d..9bafbdb1c8c3404bb2954311e64dd1cb1f5fd6f4 100644 (file)
@@ -53,8 +53,6 @@ loop-aio-inherit-the-ioprio-of-original-request.patch
 loop-stop-using-vfs_iter_-read-write-for-buffered-i-.patch
 ata-libata-sata-save-all-fields-from-sense-data-desc.patch
 cxgb4-fix-memory-leak-in-cxgb4_init_ethtool_filters-.patch
-tools-ynl-gen-individually-free-previous-values-on-d.patch
-tools-ynl-gen-make-sure-we-validate-subtype-of-array.patch
 netlink-specs-rt-link-add-an-attr-layer-around-alt-i.patch
 netlink-specs-rt-link-adjust-mctp-attribute-naming.patch
 net-b53-enable-bpdu-reception-for-management-port.patch
diff --git a/queue-6.12/tools-ynl-gen-individually-free-previous-values-on-d.patch b/queue-6.12/tools-ynl-gen-individually-free-previous-values-on-d.patch
deleted file mode 100644 (file)
index f0ccc9c..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-From 624965eab37b774683e2eb8643f22fb85c0f98cb Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 14 Apr 2025 14:18:46 -0700
-Subject: tools: ynl-gen: individually free previous values on double set
-
-From: Jakub Kicinski <kuba@kernel.org>
-
-[ Upstream commit ce6cb8113c842b94e77364b247c4f85c7b34e0c2 ]
-
-When user calls request_attrA_set() multiple times (for the same
-attribute), and attrA is of type which allocates memory -
-we try to free the previously associated values. For array
-types (including multi-attr) we have only freed the array,
-but the array may have contained pointers.
-
-Refactor the code generation for free attr and reuse the generated
-lines in setters to flush out the previous state. Since setters
-are static inlines in the header we need to add forward declarations
-for the free helpers of pure nested structs. Track which types get
-used by arrays and include the right forwad declarations.
-
-At least ethtool string set and bit set would not be freed without
-this. Tho, admittedly, overriding already set attribute twice is likely
-a very very rare thing to do.
-
-Fixes: be5bea1cc0bf ("net: add basic C code generators for Netlink")
-Reviewed-by: Donald Hunter <donald.hunter@gmail.com>
-Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
-Link: https://patch.msgid.link/20250414211851.602096-4-kuba@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/net/ynl/ynl-gen-c.py | 62 +++++++++++++++++++++++++++-----------
- 1 file changed, 45 insertions(+), 17 deletions(-)
-
-diff --git a/tools/net/ynl/ynl-gen-c.py b/tools/net/ynl/ynl-gen-c.py
-index 463f1394ab971..265a0ec0ef811 100755
---- a/tools/net/ynl/ynl-gen-c.py
-+++ b/tools/net/ynl/ynl-gen-c.py
-@@ -126,9 +126,15 @@ class Type(SpecAttr):
-     def free_needs_iter(self):
-         return False
--    def free(self, ri, var, ref):
-+    def _free_lines(self, ri, var, ref):
-         if self.is_multi_val() or self.presence_type() == 'len':
--            ri.cw.p(f'free({var}->{ref}{self.c_name});')
-+            return [f'free({var}->{ref}{self.c_name});']
-+        return []
-+
-+    def free(self, ri, var, ref):
-+        lines = self._free_lines(ri, var, ref)
-+        for line in lines:
-+            ri.cw.p(line)
-     def arg_member(self, ri):
-         member = self._complex_member_type(ri)
-@@ -224,6 +230,10 @@ class Type(SpecAttr):
-         var = "req"
-         member = f"{var}->{'.'.join(ref)}"
-+        local_vars = []
-+        if self.free_needs_iter():
-+            local_vars += ['unsigned int i;']
-+
-         code = []
-         presence = ''
-         for i in range(0, len(ref)):
-@@ -233,6 +243,10 @@ class Type(SpecAttr):
-             if i == len(ref) - 1 and self.presence_type() != 'bit':
-                 continue
-             code.append(presence + ' = 1;')
-+        ref_path = '.'.join(ref[:-1])
-+        if ref_path:
-+            ref_path += '.'
-+        code += self._free_lines(ri, var, ref_path)
-         code += self._setter_lines(ri, member, presence)
-         func_name = f"{op_prefix(ri, direction, deref=deref)}_set_{'_'.join(ref)}"
-@@ -240,7 +254,8 @@ class Type(SpecAttr):
-         alloc = bool([x for x in code if 'alloc(' in x])
-         if free and not alloc:
-             func_name = '__' + func_name
--        ri.cw.write_func('static inline void', func_name, body=code,
-+        ri.cw.write_func('static inline void', func_name, local_vars=local_vars,
-+                         body=code,
-                          args=[f'{type_name(ri, direction, deref=deref)} *{var}'] + self.arg_member(ri))
-@@ -443,8 +458,7 @@ class TypeString(Type):
-                ['unsigned int len;']
-     def _setter_lines(self, ri, member, presence):
--        return [f"free({member});",
--                f"{presence}_len = strlen({self.c_name});",
-+        return [f"{presence}_len = strlen({self.c_name});",
-                 f"{member} = malloc({presence}_len + 1);",
-                 f'memcpy({member}, {self.c_name}, {presence}_len);',
-                 f'{member}[{presence}_len] = 0;']
-@@ -490,8 +504,7 @@ class TypeBinary(Type):
-                ['unsigned int len;']
-     def _setter_lines(self, ri, member, presence):
--        return [f"free({member});",
--                f"{presence}_len = len;",
-+        return [f"{presence}_len = len;",
-                 f"{member} = malloc({presence}_len);",
-                 f'memcpy({member}, {self.c_name}, {presence}_len);']
-@@ -528,12 +541,14 @@ class TypeNest(Type):
-     def _complex_member_type(self, ri):
-         return self.nested_struct_type
--    def free(self, ri, var, ref):
-+    def _free_lines(self, ri, var, ref):
-+        lines = []
-         at = '&'
-         if self.is_recursive_for_op(ri):
-             at = ''
--            ri.cw.p(f'if ({var}->{ref}{self.c_name})')
--        ri.cw.p(f'{self.nested_render_name}_free({at}{var}->{ref}{self.c_name});')
-+            lines += [f'if ({var}->{ref}{self.c_name})']
-+        lines += [f'{self.nested_render_name}_free({at}{var}->{ref}{self.c_name});']
-+        return lines
-     def _attr_typol(self):
-         return f'.type = YNL_PT_NEST, .nest = &{self.nested_render_name}_nest, '
-@@ -586,15 +601,19 @@ class TypeMultiAttr(Type):
-     def free_needs_iter(self):
-         return 'type' not in self.attr or self.attr['type'] == 'nest'
--    def free(self, ri, var, ref):
-+    def _free_lines(self, ri, var, ref):
-+        lines = []
-         if self.attr['type'] in scalars:
--            ri.cw.p(f"free({var}->{ref}{self.c_name});")
-+            lines += [f"free({var}->{ref}{self.c_name});"]
-         elif 'type' not in self.attr or self.attr['type'] == 'nest':
--            ri.cw.p(f"for (i = 0; i < {var}->{ref}n_{self.c_name}; i++)")
--            ri.cw.p(f'{self.nested_render_name}_free(&{var}->{ref}{self.c_name}[i]);')
--            ri.cw.p(f"free({var}->{ref}{self.c_name});")
-+            lines += [
-+                f"for (i = 0; i < {var}->{ref}n_{self.c_name}; i++)",
-+                f'{self.nested_render_name}_free(&{var}->{ref}{self.c_name}[i]);',
-+                f"free({var}->{ref}{self.c_name});",
-+            ]
-         else:
-             raise Exception(f"Free of MultiAttr sub-type {self.attr['type']} not supported yet")
-+        return lines
-     def _attr_policy(self, policy):
-         return self.base_type._attr_policy(policy)
-@@ -620,8 +639,7 @@ class TypeMultiAttr(Type):
-     def _setter_lines(self, ri, member, presence):
-         # For multi-attr we have a count, not presence, hack up the presence
-         presence = presence[:-(len('_present.') + len(self.c_name))] + "n_" + self.c_name
--        return [f"free({member});",
--                f"{member} = {self.c_name};",
-+        return [f"{member} = {self.c_name};",
-                 f"{presence} = n_{self.c_name};"]
-@@ -706,6 +724,7 @@ class Struct:
-         self.request = False
-         self.reply = False
-         self.recursive = False
-+        self.in_multi_val = False  # used by a MultiAttr or and legacy arrays
-         self.attr_list = []
-         self.attrs = dict()
-@@ -1071,6 +1090,10 @@ class Family(SpecFamily):
-                     if attr in rs_members['reply']:
-                         self.pure_nested_structs[nested].reply = True
-+                if spec.is_multi_val():
-+                    child = self.pure_nested_structs.get(nested)
-+                    child.in_multi_val = True
-+
-         self._sort_pure_types()
-         # Propagate the request / reply / recursive
-@@ -1085,6 +1108,8 @@ class Family(SpecFamily):
-                             struct.child_nests.update(child.child_nests)
-                         child.request |= struct.request
-                         child.reply |= struct.reply
-+                        if spec.is_multi_val():
-+                            child.in_multi_val = True
-                 if attr_set in struct.child_nests:
-                     struct.recursive = True
-@@ -2794,6 +2819,9 @@ 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} ============== */")
--- 
-2.39.5
-
diff --git a/queue-6.12/tools-ynl-gen-make-sure-we-validate-subtype-of-array.patch b/queue-6.12/tools-ynl-gen-make-sure-we-validate-subtype-of-array.patch
deleted file mode 100644 (file)
index a51d9e6..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-From 0d29e4654faad31df924e67e0609de22cce40449 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 14 Apr 2025 14:18:47 -0700
-Subject: tools: ynl-gen: make sure we validate subtype of array-nest
-
-From: Jakub Kicinski <kuba@kernel.org>
-
-[ Upstream commit 57e7dedf2b8c72caa6f04b9e08b19e4f370562fa ]
-
-ArrayNest AKA indexed-array support currently skips inner type
-validation. We count the attributes and then we parse them,
-make sure we call validate, too. Otherwise buggy / unexpected
-kernel response may lead to crashes.
-
-Fixes: be5bea1cc0bf ("net: add basic C code generators for Netlink")
-Reviewed-by: Donald Hunter <donald.hunter@gmail.com>
-Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
-Link: https://patch.msgid.link/20250414211851.602096-5-kuba@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/net/ynl/ynl-gen-c.py | 7 +++++--
- 1 file changed, 5 insertions(+), 2 deletions(-)
-
-diff --git a/tools/net/ynl/ynl-gen-c.py b/tools/net/ynl/ynl-gen-c.py
-index 265a0ec0ef811..40f1c3631f985 100755
---- a/tools/net/ynl/ynl-gen-c.py
-+++ b/tools/net/ynl/ynl-gen-c.py
-@@ -665,8 +665,11 @@ class TypeArrayNest(Type):
-     def _attr_get(self, ri, var):
-         local_vars = ['const struct nlattr *attr2;']
-         get_lines = [f'attr_{self.c_name} = attr;',
--                     'ynl_attr_for_each_nested(attr2, attr)',
--                     f'\t{var}->n_{self.c_name}++;']
-+                     'ynl_attr_for_each_nested(attr2, attr) {',
-+                     '\tif (ynl_attr_validate(yarg, attr2))',
-+                     '\t\treturn YNL_PARSE_CB_ERROR;',
-+                     f'\t{var}->n_{self.c_name}++;',
-+                     '}']
-         return get_lines, None, local_vars
--- 
-2.39.5
-
index 40bb08b16af6af405e13b7e689747b07d49de73a..8678ff04e5bbb43f6546a266493e1c7274c6f5d4 100644 (file)
@@ -62,8 +62,6 @@ nvmet-pci-epf-always-fully-initialize-completion-ent.patch
 nvmet-pci-epf-clear-cc-and-csts-when-disabling-the-c.patch
 ata-libata-sata-save-all-fields-from-sense-data-desc.patch
 cxgb4-fix-memory-leak-in-cxgb4_init_ethtool_filters-.patch
-tools-ynl-gen-individually-free-previous-values-on-d.patch
-tools-ynl-gen-make-sure-we-validate-subtype-of-array.patch
 netlink-specs-rt-link-add-an-attr-layer-around-alt-i.patch
 netlink-specs-rtnetlink-attribute-naming-corrections.patch
 netlink-specs-rt-link-adjust-mctp-attribute-naming.patch
diff --git a/queue-6.14/tools-ynl-gen-individually-free-previous-values-on-d.patch b/queue-6.14/tools-ynl-gen-individually-free-previous-values-on-d.patch
deleted file mode 100644 (file)
index ca11701..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-From 6abb31e231b2e22e26349d0aa7b351841a506690 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 14 Apr 2025 14:18:46 -0700
-Subject: tools: ynl-gen: individually free previous values on double set
-
-From: Jakub Kicinski <kuba@kernel.org>
-
-[ Upstream commit ce6cb8113c842b94e77364b247c4f85c7b34e0c2 ]
-
-When user calls request_attrA_set() multiple times (for the same
-attribute), and attrA is of type which allocates memory -
-we try to free the previously associated values. For array
-types (including multi-attr) we have only freed the array,
-but the array may have contained pointers.
-
-Refactor the code generation for free attr and reuse the generated
-lines in setters to flush out the previous state. Since setters
-are static inlines in the header we need to add forward declarations
-for the free helpers of pure nested structs. Track which types get
-used by arrays and include the right forwad declarations.
-
-At least ethtool string set and bit set would not be freed without
-this. Tho, admittedly, overriding already set attribute twice is likely
-a very very rare thing to do.
-
-Fixes: be5bea1cc0bf ("net: add basic C code generators for Netlink")
-Reviewed-by: Donald Hunter <donald.hunter@gmail.com>
-Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
-Link: https://patch.msgid.link/20250414211851.602096-4-kuba@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/net/ynl/pyynl/ynl_gen_c.py | 62 +++++++++++++++++++++++---------
- 1 file changed, 45 insertions(+), 17 deletions(-)
-
-diff --git a/tools/net/ynl/pyynl/ynl_gen_c.py b/tools/net/ynl/pyynl/ynl_gen_c.py
-index c2eabc90dce8c..9c9a62a93afe7 100755
---- a/tools/net/ynl/pyynl/ynl_gen_c.py
-+++ b/tools/net/ynl/pyynl/ynl_gen_c.py
-@@ -157,9 +157,15 @@ class Type(SpecAttr):
-     def free_needs_iter(self):
-         return False
--    def free(self, ri, var, ref):
-+    def _free_lines(self, ri, var, ref):
-         if self.is_multi_val() or self.presence_type() == 'len':
--            ri.cw.p(f'free({var}->{ref}{self.c_name});')
-+            return [f'free({var}->{ref}{self.c_name});']
-+        return []
-+
-+    def free(self, ri, var, ref):
-+        lines = self._free_lines(ri, var, ref)
-+        for line in lines:
-+            ri.cw.p(line)
-     def arg_member(self, ri):
-         member = self._complex_member_type(ri)
-@@ -258,6 +264,10 @@ class Type(SpecAttr):
-         var = "req"
-         member = f"{var}->{'.'.join(ref)}"
-+        local_vars = []
-+        if self.free_needs_iter():
-+            local_vars += ['unsigned int i;']
-+
-         code = []
-         presence = ''
-         for i in range(0, len(ref)):
-@@ -267,6 +277,10 @@ class Type(SpecAttr):
-             if i == len(ref) - 1 and self.presence_type() != 'bit':
-                 continue
-             code.append(presence + ' = 1;')
-+        ref_path = '.'.join(ref[:-1])
-+        if ref_path:
-+            ref_path += '.'
-+        code += self._free_lines(ri, var, ref_path)
-         code += self._setter_lines(ri, member, presence)
-         func_name = f"{op_prefix(ri, direction, deref=deref)}_set_{'_'.join(ref)}"
-@@ -274,7 +288,8 @@ class Type(SpecAttr):
-         alloc = bool([x for x in code if 'alloc(' in x])
-         if free and not alloc:
-             func_name = '__' + func_name
--        ri.cw.write_func('static inline void', func_name, body=code,
-+        ri.cw.write_func('static inline void', func_name, local_vars=local_vars,
-+                         body=code,
-                          args=[f'{type_name(ri, direction, deref=deref)} *{var}'] + self.arg_member(ri))
-@@ -477,8 +492,7 @@ class TypeString(Type):
-                ['unsigned int len;']
-     def _setter_lines(self, ri, member, presence):
--        return [f"free({member});",
--                f"{presence}_len = strlen({self.c_name});",
-+        return [f"{presence}_len = strlen({self.c_name});",
-                 f"{member} = malloc({presence}_len + 1);",
-                 f'memcpy({member}, {self.c_name}, {presence}_len);',
-                 f'{member}[{presence}_len] = 0;']
-@@ -531,8 +545,7 @@ class TypeBinary(Type):
-                ['unsigned int len;']
-     def _setter_lines(self, ri, member, presence):
--        return [f"free({member});",
--                f"{presence}_len = len;",
-+        return [f"{presence}_len = len;",
-                 f"{member} = malloc({presence}_len);",
-                 f'memcpy({member}, {self.c_name}, {presence}_len);']
-@@ -569,12 +582,14 @@ class TypeNest(Type):
-     def _complex_member_type(self, ri):
-         return self.nested_struct_type
--    def free(self, ri, var, ref):
-+    def _free_lines(self, ri, var, ref):
-+        lines = []
-         at = '&'
-         if self.is_recursive_for_op(ri):
-             at = ''
--            ri.cw.p(f'if ({var}->{ref}{self.c_name})')
--        ri.cw.p(f'{self.nested_render_name}_free({at}{var}->{ref}{self.c_name});')
-+            lines += [f'if ({var}->{ref}{self.c_name})']
-+        lines += [f'{self.nested_render_name}_free({at}{var}->{ref}{self.c_name});']
-+        return lines
-     def _attr_typol(self):
-         return f'.type = YNL_PT_NEST, .nest = &{self.nested_render_name}_nest, '
-@@ -627,15 +642,19 @@ class TypeMultiAttr(Type):
-     def free_needs_iter(self):
-         return 'type' not in self.attr or self.attr['type'] == 'nest'
--    def free(self, ri, var, ref):
-+    def _free_lines(self, ri, var, ref):
-+        lines = []
-         if self.attr['type'] in scalars:
--            ri.cw.p(f"free({var}->{ref}{self.c_name});")
-+            lines += [f"free({var}->{ref}{self.c_name});"]
-         elif 'type' not in self.attr or self.attr['type'] == 'nest':
--            ri.cw.p(f"for (i = 0; i < {var}->{ref}n_{self.c_name}; i++)")
--            ri.cw.p(f'{self.nested_render_name}_free(&{var}->{ref}{self.c_name}[i]);')
--            ri.cw.p(f"free({var}->{ref}{self.c_name});")
-+            lines += [
-+                f"for (i = 0; i < {var}->{ref}n_{self.c_name}; i++)",
-+                f'{self.nested_render_name}_free(&{var}->{ref}{self.c_name}[i]);',
-+                f"free({var}->{ref}{self.c_name});",
-+            ]
-         else:
-             raise Exception(f"Free of MultiAttr sub-type {self.attr['type']} not supported yet")
-+        return lines
-     def _attr_policy(self, policy):
-         return self.base_type._attr_policy(policy)
-@@ -661,8 +680,7 @@ class TypeMultiAttr(Type):
-     def _setter_lines(self, ri, member, presence):
-         # For multi-attr we have a count, not presence, hack up the presence
-         presence = presence[:-(len('_present.') + len(self.c_name))] + "n_" + self.c_name
--        return [f"free({member});",
--                f"{member} = {self.c_name};",
-+        return [f"{member} = {self.c_name};",
-                 f"{presence} = n_{self.c_name};"]
-@@ -747,6 +765,7 @@ class Struct:
-         self.request = False
-         self.reply = False
-         self.recursive = False
-+        self.in_multi_val = False  # used by a MultiAttr or and legacy arrays
-         self.attr_list = []
-         self.attrs = dict()
-@@ -1114,6 +1133,10 @@ class Family(SpecFamily):
-                     if attr in rs_members['reply']:
-                         self.pure_nested_structs[nested].reply = True
-+                if spec.is_multi_val():
-+                    child = self.pure_nested_structs.get(nested)
-+                    child.in_multi_val = True
-+
-         self._sort_pure_types()
-         # Propagate the request / reply / recursive
-@@ -1128,6 +1151,8 @@ class Family(SpecFamily):
-                             struct.child_nests.update(child.child_nests)
-                         child.request |= struct.request
-                         child.reply |= struct.reply
-+                        if spec.is_multi_val():
-+                            child.in_multi_val = True
-                 if attr_set in struct.child_nests:
-                     struct.recursive = True
-@@ -2921,6 +2946,9 @@ 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} ============== */")
--- 
-2.39.5
-
diff --git a/queue-6.14/tools-ynl-gen-make-sure-we-validate-subtype-of-array.patch b/queue-6.14/tools-ynl-gen-make-sure-we-validate-subtype-of-array.patch
deleted file mode 100644 (file)
index f0d84f3..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-From c136cc6535a7454c9e1a66fc0c934aae20134cbe Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 14 Apr 2025 14:18:47 -0700
-Subject: tools: ynl-gen: make sure we validate subtype of array-nest
-
-From: Jakub Kicinski <kuba@kernel.org>
-
-[ Upstream commit 57e7dedf2b8c72caa6f04b9e08b19e4f370562fa ]
-
-ArrayNest AKA indexed-array support currently skips inner type
-validation. We count the attributes and then we parse them,
-make sure we call validate, too. Otherwise buggy / unexpected
-kernel response may lead to crashes.
-
-Fixes: be5bea1cc0bf ("net: add basic C code generators for Netlink")
-Reviewed-by: Donald Hunter <donald.hunter@gmail.com>
-Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
-Link: https://patch.msgid.link/20250414211851.602096-5-kuba@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/net/ynl/pyynl/ynl_gen_c.py | 7 +++++--
- 1 file changed, 5 insertions(+), 2 deletions(-)
-
-diff --git a/tools/net/ynl/pyynl/ynl_gen_c.py b/tools/net/ynl/pyynl/ynl_gen_c.py
-index 9c9a62a93afe7..f36af0e1da78e 100755
---- a/tools/net/ynl/pyynl/ynl_gen_c.py
-+++ b/tools/net/ynl/pyynl/ynl_gen_c.py
-@@ -706,8 +706,11 @@ class TypeArrayNest(Type):
-     def _attr_get(self, ri, var):
-         local_vars = ['const struct nlattr *attr2;']
-         get_lines = [f'attr_{self.c_name} = attr;',
--                     'ynl_attr_for_each_nested(attr2, attr)',
--                     f'\t{var}->n_{self.c_name}++;']
-+                     'ynl_attr_for_each_nested(attr2, attr) {',
-+                     '\tif (ynl_attr_validate(yarg, attr2))',
-+                     '\t\treturn YNL_PARSE_CB_ERROR;',
-+                     f'\t{var}->n_{self.c_name}++;',
-+                     '}']
-         return get_lines, None, local_vars
--- 
-2.39.5
-
index 263864e67d80cf5207209dce91d0e35fe53a24ef..2c0a3fc8e0801f6077e4e0e654fd02ff3982fdbf 100644 (file)
@@ -272,11 +272,6 @@ net-ethernet-ti-am65-cpsw-nuss-rename-phy_node-port_.patch
 net-ethernet-ti-am65-cpsw-fix-port_np-reference-coun.patch
 ata-libata-sata-save-all-fields-from-sense-data-desc.patch
 cxgb4-fix-memory-leak-in-cxgb4_init_ethtool_filters-.patch
-tools-ynl-gen-track-attribute-use.patch
-tools-ynl-gen-record-information-about-recursive-nes.patch
-tools-ynl-gen-re-sort-ignoring-recursive-nests.patch
-tools-ynl-gen-store-recursive-nests-by-a-pointer.patch
-tools-ynl-gen-individually-free-previous-values-on-d.patch
 netlink-specs-rt-link-add-an-attr-layer-around-alt-i.patch
 netlink-specs-rt-link-adjust-mctp-attribute-naming.patch
 net-b53-enable-bpdu-reception-for-management-port.patch
diff --git a/queue-6.6/tools-ynl-gen-individually-free-previous-values-on-d.patch b/queue-6.6/tools-ynl-gen-individually-free-previous-values-on-d.patch
deleted file mode 100644 (file)
index e4b5c9b..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-From 5604949695e5b874289ce8143d8a4c1e1fe97374 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 14 Apr 2025 14:18:46 -0700
-Subject: tools: ynl-gen: individually free previous values on double set
-
-From: Jakub Kicinski <kuba@kernel.org>
-
-[ Upstream commit ce6cb8113c842b94e77364b247c4f85c7b34e0c2 ]
-
-When user calls request_attrA_set() multiple times (for the same
-attribute), and attrA is of type which allocates memory -
-we try to free the previously associated values. For array
-types (including multi-attr) we have only freed the array,
-but the array may have contained pointers.
-
-Refactor the code generation for free attr and reuse the generated
-lines in setters to flush out the previous state. Since setters
-are static inlines in the header we need to add forward declarations
-for the free helpers of pure nested structs. Track which types get
-used by arrays and include the right forwad declarations.
-
-At least ethtool string set and bit set would not be freed without
-this. Tho, admittedly, overriding already set attribute twice is likely
-a very very rare thing to do.
-
-Fixes: be5bea1cc0bf ("net: add basic C code generators for Netlink")
-Reviewed-by: Donald Hunter <donald.hunter@gmail.com>
-Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
-Link: https://patch.msgid.link/20250414211851.602096-4-kuba@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/net/ynl/ynl-gen-c.py | 62 +++++++++++++++++++++++++++-----------
- 1 file changed, 45 insertions(+), 17 deletions(-)
-
-diff --git a/tools/net/ynl/ynl-gen-c.py b/tools/net/ynl/ynl-gen-c.py
-index 9e37d14d76bf9..53c86d3897e13 100755
---- a/tools/net/ynl/ynl-gen-c.py
-+++ b/tools/net/ynl/ynl-gen-c.py
-@@ -107,9 +107,15 @@ class Type(SpecAttr):
-     def free_needs_iter(self):
-         return False
--    def free(self, ri, var, ref):
-+    def _free_lines(self, ri, var, ref):
-         if self.is_multi_val() or self.presence_type() == 'len':
--            ri.cw.p(f'free({var}->{ref}{self.c_name});')
-+            return [f'free({var}->{ref}{self.c_name});']
-+        return []
-+
-+    def free(self, ri, var, ref):
-+        lines = self._free_lines(ri, var, ref)
-+        for line in lines:
-+            ri.cw.p(line)
-     def arg_member(self, ri):
-         member = self._complex_member_type(ri)
-@@ -205,6 +211,10 @@ class Type(SpecAttr):
-         var = "req"
-         member = f"{var}->{'.'.join(ref)}"
-+        local_vars = []
-+        if self.free_needs_iter():
-+            local_vars += ['unsigned int i;']
-+
-         code = []
-         presence = ''
-         for i in range(0, len(ref)):
-@@ -214,6 +224,10 @@ class Type(SpecAttr):
-             if i == len(ref) - 1 and self.presence_type() != 'bit':
-                 continue
-             code.append(presence + ' = 1;')
-+        ref_path = '.'.join(ref[:-1])
-+        if ref_path:
-+            ref_path += '.'
-+        code += self._free_lines(ri, var, ref_path)
-         code += self._setter_lines(ri, member, presence)
-         func_name = f"{op_prefix(ri, direction, deref=deref)}_set_{'_'.join(ref)}"
-@@ -221,7 +235,8 @@ class Type(SpecAttr):
-         alloc = bool([x for x in code if 'alloc(' in x])
-         if free and not alloc:
-             func_name = '__' + func_name
--        ri.cw.write_func('static inline void', func_name, body=code,
-+        ri.cw.write_func('static inline void', func_name, local_vars=local_vars,
-+                         body=code,
-                          args=[f'{type_name(ri, direction, deref=deref)} *{var}'] + self.arg_member(ri))
-@@ -397,8 +412,7 @@ class TypeString(Type):
-                ['unsigned int len;']
-     def _setter_lines(self, ri, member, presence):
--        return [f"free({member});",
--                f"{presence}_len = strlen({self.c_name});",
-+        return [f"{presence}_len = strlen({self.c_name});",
-                 f"{member} = malloc({presence}_len + 1);",
-                 f'memcpy({member}, {self.c_name}, {presence}_len);',
-                 f'{member}[{presence}_len] = 0;']
-@@ -441,8 +455,7 @@ class TypeBinary(Type):
-                ['unsigned int len;']
-     def _setter_lines(self, ri, member, presence):
--        return [f"free({member});",
--                f"{presence}_len = len;",
-+        return [f"{presence}_len = len;",
-                 f"{member} = malloc({presence}_len);",
-                 f'memcpy({member}, {self.c_name}, {presence}_len);']
-@@ -454,12 +467,14 @@ class TypeNest(Type):
-     def _complex_member_type(self, ri):
-         return self.nested_struct_type
--    def free(self, ri, var, ref):
-+    def _free_lines(self, ri, var, ref):
-+        lines = []
-         at = '&'
-         if self.is_recursive_for_op(ri):
-             at = ''
--            ri.cw.p(f'if ({var}->{ref}{self.c_name})')
--        ri.cw.p(f'{self.nested_render_name}_free({at}{var}->{ref}{self.c_name});')
-+            lines += [f'if ({var}->{ref}{self.c_name})']
-+        lines += [f'{self.nested_render_name}_free({at}{var}->{ref}{self.c_name});']
-+        return lines
-     def _attr_typol(self):
-         return f'.type = YNL_PT_NEST, .nest = &{self.nested_render_name}_nest, '
-@@ -519,15 +534,19 @@ class TypeMultiAttr(Type):
-     def free_needs_iter(self):
-         return 'type' not in self.attr or self.attr['type'] == 'nest'
--    def free(self, ri, var, ref):
-+    def _free_lines(self, ri, var, ref):
-+        lines = []
-         if self.attr['type'] in scalars:
--            ri.cw.p(f"free({var}->{ref}{self.c_name});")
-+            lines += [f"free({var}->{ref}{self.c_name});"]
-         elif 'type' not in self.attr or self.attr['type'] == 'nest':
--            ri.cw.p(f"for (i = 0; i < {var}->{ref}n_{self.c_name}; i++)")
--            ri.cw.p(f'{self.nested_render_name}_free(&{var}->{ref}{self.c_name}[i]);')
--            ri.cw.p(f"free({var}->{ref}{self.c_name});")
-+            lines += [
-+                f"for (i = 0; i < {var}->{ref}n_{self.c_name}; i++)",
-+                f'{self.nested_render_name}_free(&{var}->{ref}{self.c_name}[i]);',
-+                f"free({var}->{ref}{self.c_name});",
-+            ]
-         else:
-             raise Exception(f"Free of MultiAttr sub-type {self.attr['type']} not supported yet")
-+        return lines
-     def _attr_policy(self, policy):
-         return self.base_type._attr_policy(policy)
-@@ -553,8 +572,7 @@ class TypeMultiAttr(Type):
-     def _setter_lines(self, ri, member, presence):
-         # For multi-attr we have a count, not presence, hack up the presence
-         presence = presence[:-(len('_present.') + len(self.c_name))] + "n_" + self.c_name
--        return [f"free({member});",
--                f"{member} = {self.c_name};",
-+        return [f"{member} = {self.c_name};",
-                 f"{presence} = n_{self.c_name};"]
-@@ -639,6 +657,7 @@ class Struct:
-         self.request = False
-         self.reply = False
-         self.recursive = False
-+        self.in_multi_val = False  # used by a MultiAttr or and legacy arrays
-         self.attr_list = []
-         self.attrs = dict()
-@@ -987,6 +1006,10 @@ class Family(SpecFamily):
-                     if attr in rs_members['reply']:
-                         self.pure_nested_structs[nested].reply = True
-+                if spec.is_multi_val():
-+                    child = self.pure_nested_structs.get(nested)
-+                    child.in_multi_val = True
-+
-         self._sort_pure_types()
-         # Propagate the request / reply / recursive
-@@ -1001,6 +1024,8 @@ class Family(SpecFamily):
-                             struct.child_nests.update(child.child_nests)
-                         child.request |= struct.request
-                         child.reply |= struct.reply
-+                        if spec.is_multi_val():
-+                            child.in_multi_val = True
-                 if attr_set in struct.child_nests:
-                     struct.recursive = True
-@@ -2552,6 +2577,9 @@ 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} ============== */")
--- 
-2.39.5
-
diff --git a/queue-6.6/tools-ynl-gen-re-sort-ignoring-recursive-nests.patch b/queue-6.6/tools-ynl-gen-re-sort-ignoring-recursive-nests.patch
deleted file mode 100644 (file)
index b83b93e..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-From 81bea2ea7c3b5153dd4f58b111ee44f9bca2cb46 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 13 Dec 2023 15:14:30 -0800
-Subject: tools: ynl-gen: re-sort ignoring recursive nests
-
-From: Jakub Kicinski <kuba@kernel.org>
-
-[ Upstream commit aa75783b95a1e7fc09129f5364476e6effe47392 ]
-
-We try to keep the structures and helpers "topologically sorted",
-to avoid forward declarations. When recursive nests are at play
-we need to sort twice, because structs which end up being marked
-as recursive will get a full set of forward declarations, so we
-should ignore them for the purpose of sorting.
-
-Reviewed-by: Donald Hunter <donald.hunter@gmail.com>
-Link: https://lore.kernel.org/r/20231213231432.2944749-7-kuba@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Stable-dep-of: ce6cb8113c84 ("tools: ynl-gen: individually free previous values on double set")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/net/ynl/ynl-gen-c.py | 52 +++++++++++++++++++++++---------------
- 1 file changed, 31 insertions(+), 21 deletions(-)
-
-diff --git a/tools/net/ynl/ynl-gen-c.py b/tools/net/ynl/ynl-gen-c.py
-index e5a3e0bb5a39d..502d03b8a758a 100755
---- a/tools/net/ynl/ynl-gen-c.py
-+++ b/tools/net/ynl/ynl-gen-c.py
-@@ -909,6 +909,33 @@ class Family(SpecFamily):
-                 self.root_sets[op['attribute-set']]['request'].update(req_attrs)
-                 self.root_sets[op['attribute-set']]['reply'].update(rsp_attrs)
-+    def _sort_pure_types(self):
-+        # Try to reorder according to dependencies
-+        pns_key_list = list(self.pure_nested_structs.keys())
-+        pns_key_seen = set()
-+        rounds = len(pns_key_list) ** 2  # it's basically bubble sort
-+        for _ in range(rounds):
-+            if len(pns_key_list) == 0:
-+                break
-+            name = pns_key_list.pop(0)
-+            finished = True
-+            for _, spec in self.attr_sets[name].items():
-+                if 'nested-attributes' in spec:
-+                    nested = spec['nested-attributes']
-+                    # If the unknown nest we hit is recursive it's fine, it'll be a pointer
-+                    if self.pure_nested_structs[nested].recursive:
-+                        continue
-+                    if nested not in pns_key_seen:
-+                        # Dicts are sorted, this will make struct last
-+                        struct = self.pure_nested_structs.pop(name)
-+                        self.pure_nested_structs[name] = struct
-+                        finished = False
-+                        break
-+            if finished:
-+                pns_key_seen.add(name)
-+            else:
-+                pns_key_list.append(name)
-+
-     def _load_nested_sets(self):
-         attr_set_queue = list(self.root_sets.keys())
-         attr_set_seen = set(self.root_sets.keys())
-@@ -948,27 +975,8 @@ class Family(SpecFamily):
-                     if attr in rs_members['reply']:
-                         self.pure_nested_structs[nested].reply = True
--        # Try to reorder according to dependencies
--        pns_key_list = list(self.pure_nested_structs.keys())
--        pns_key_seen = set()
--        rounds = len(pns_key_list)**2  # it's basically bubble sort
--        for _ in range(rounds):
--            if len(pns_key_list) == 0:
--                break
--            name = pns_key_list.pop(0)
--            finished = True
--            for _, spec in self.attr_sets[name].items():
--                if 'nested-attributes' in spec:
--                    if spec['nested-attributes'] not in pns_key_seen:
--                        # Dicts are sorted, this will make struct last
--                        struct = self.pure_nested_structs.pop(name)
--                        self.pure_nested_structs[name] = struct
--                        finished = False
--                        break
--            if finished:
--                pns_key_seen.add(name)
--            else:
--                pns_key_list.append(name)
-+        self._sort_pure_types()
-+
-         # Propagate the request / reply / recursive
-         for attr_set, struct in reversed(self.pure_nested_structs.items()):
-             for _, spec in self.attr_sets[attr_set].items():
-@@ -984,6 +992,8 @@ class Family(SpecFamily):
-                 if attr_set in struct.child_nests:
-                     struct.recursive = True
-+        self._sort_pure_types()
-+
-     def _load_attr_use(self):
-         for _, struct in self.pure_nested_structs.items():
-             if struct.request:
--- 
-2.39.5
-
diff --git a/queue-6.6/tools-ynl-gen-record-information-about-recursive-nes.patch b/queue-6.6/tools-ynl-gen-record-information-about-recursive-nes.patch
deleted file mode 100644 (file)
index 8630d4e..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-From e81c87860379f30670ad0505ebad1fcc30330348 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 13 Dec 2023 15:14:29 -0800
-Subject: tools: ynl-gen: record information about recursive nests
-
-From: Jakub Kicinski <kuba@kernel.org>
-
-[ Upstream commit 38329fcfb757b8215c07a77b6657721cc7e9530e ]
-
-Track which nests are recursive. Non-recursive nesting gets
-rendered in C as directly nested structs. For recursive
-ones we need to put a pointer in, rather than full struct.
-
-Track this information, no change to generated code, yet.
-
-Reviewed-by: Donald Hunter <donald.hunter@gmail.com>
-Link: https://lore.kernel.org/r/20231213231432.2944749-6-kuba@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Stable-dep-of: ce6cb8113c84 ("tools: ynl-gen: individually free previous values on double set")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/net/ynl/ynl-gen-c.py | 19 +++++++++++++++++--
- 1 file changed, 17 insertions(+), 2 deletions(-)
-
-diff --git a/tools/net/ynl/ynl-gen-c.py b/tools/net/ynl/ynl-gen-c.py
-index 4c86fe0cd1179..e5a3e0bb5a39d 100755
---- a/tools/net/ynl/ynl-gen-c.py
-+++ b/tools/net/ynl/ynl-gen-c.py
-@@ -80,6 +80,9 @@ class Type(SpecAttr):
-     def is_scalar(self):
-         return self.type in {'u8', 'u16', 'u32', 'u64', 's32', 's64'}
-+    def is_recursive(self):
-+        return False
-+
-     def presence_type(self):
-         return 'bit'
-@@ -440,6 +443,9 @@ class TypeBinary(Type):
- class TypeNest(Type):
-+    def is_recursive(self):
-+        return self.family.pure_nested_structs[self.nested_attrs].recursive
-+
-     def _complex_member_type(self, ri):
-         return self.nested_struct_type
-@@ -615,9 +621,12 @@ class Struct:
-         if self.nested and space_name in family.consts:
-             self.struct_name += '_'
-         self.ptr_name = self.struct_name + ' *'
-+        # All attr sets this one contains, directly or multiple levels down
-+        self.child_nests = set()
-         self.request = False
-         self.reply = False
-+        self.recursive = False
-         self.attr_list = []
-         self.attrs = dict()
-@@ -960,14 +969,20 @@ class Family(SpecFamily):
-                 pns_key_seen.add(name)
-             else:
-                 pns_key_list.append(name)
--        # Propagate the request / reply
-+        # Propagate the request / reply / recursive
-         for attr_set, struct in reversed(self.pure_nested_structs.items()):
-             for _, spec in self.attr_sets[attr_set].items():
-                 if 'nested-attributes' in spec:
--                    child = self.pure_nested_structs.get(spec['nested-attributes'])
-+                    child_name = spec['nested-attributes']
-+                    struct.child_nests.add(child_name)
-+                    child = self.pure_nested_structs.get(child_name)
-                     if child:
-+                        if not child.recursive:
-+                            struct.child_nests.update(child.child_nests)
-                         child.request |= struct.request
-                         child.reply |= struct.reply
-+                if attr_set in struct.child_nests:
-+                    struct.recursive = True
-     def _load_attr_use(self):
-         for _, struct in self.pure_nested_structs.items():
--- 
-2.39.5
-
diff --git a/queue-6.6/tools-ynl-gen-store-recursive-nests-by-a-pointer.patch b/queue-6.6/tools-ynl-gen-store-recursive-nests-by-a-pointer.patch
deleted file mode 100644 (file)
index 7e6a72b..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-From 0558ef104f9aecdb8be03b564438e99cad3b597e Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 13 Dec 2023 15:14:31 -0800
-Subject: tools: ynl-gen: store recursive nests by a pointer
-
-From: Jakub Kicinski <kuba@kernel.org>
-
-[ Upstream commit 461f25a2e4334767d3e306b08dbda054da1aaa30 ]
-
-To avoid infinite nesting store recursive structs by pointer.
-If recursive struct is placed in the op directly - the first
-instance can be stored by value. That makes the code much
-less of a pain for majority of practical uses.
-
-Reviewed-by: Donald Hunter <donald.hunter@gmail.com>
-Link: https://lore.kernel.org/r/20231213231432.2944749-8-kuba@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Stable-dep-of: ce6cb8113c84 ("tools: ynl-gen: individually free previous values on double set")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/net/ynl/ynl-gen-c.py | 16 ++++++++++++++--
- 1 file changed, 14 insertions(+), 2 deletions(-)
-
-diff --git a/tools/net/ynl/ynl-gen-c.py b/tools/net/ynl/ynl-gen-c.py
-index 502d03b8a758a..9e37d14d76bf9 100755
---- a/tools/net/ynl/ynl-gen-c.py
-+++ b/tools/net/ynl/ynl-gen-c.py
-@@ -83,6 +83,9 @@ class Type(SpecAttr):
-     def is_recursive(self):
-         return False
-+    def is_recursive_for_op(self, ri):
-+        return self.is_recursive() and not ri.op
-+
-     def presence_type(self):
-         return 'bit'
-@@ -123,6 +126,8 @@ class Type(SpecAttr):
-         member = self._complex_member_type(ri)
-         if member:
-             ptr = '*' if self.is_multi_val() else ''
-+            if self.is_recursive_for_op(ri):
-+                ptr = '*'
-             ri.cw.p(f"{member} {ptr}{self.c_name};")
-             return
-         members = self.arg_member(ri)
-@@ -450,7 +455,11 @@ class TypeNest(Type):
-         return self.nested_struct_type
-     def free(self, ri, var, ref):
--        ri.cw.p(f'{self.nested_render_name}_free(&{var}->{ref}{self.c_name});')
-+        at = '&'
-+        if self.is_recursive_for_op(ri):
-+            at = ''
-+            ri.cw.p(f'if ({var}->{ref}{self.c_name})')
-+        ri.cw.p(f'{self.nested_render_name}_free({at}{var}->{ref}{self.c_name});')
-     def _attr_typol(self):
-         return f'.type = YNL_PT_NEST, .nest = &{self.nested_render_name}_nest, '
-@@ -459,8 +468,9 @@ class TypeNest(Type):
-         return 'NLA_POLICY_NESTED(' + self.nested_render_name + '_nl_policy)'
-     def attr_put(self, ri, var):
-+        at = '' if self.is_recursive_for_op(ri) else '&'
-         self._attr_put_line(ri, var, f"{self.nested_render_name}_put(nlh, " +
--                            f"{self.enum_name}, &{var}->{self.c_name})")
-+                            f"{self.enum_name}, {at}{var}->{self.c_name})")
-     def _attr_get(self, ri, var):
-         get_lines = [f"if ({self.nested_render_name}_parse(&parg, attr))",
-@@ -473,6 +483,8 @@ class TypeNest(Type):
-         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)
--- 
-2.39.5
-
diff --git a/queue-6.6/tools-ynl-gen-track-attribute-use.patch b/queue-6.6/tools-ynl-gen-track-attribute-use.patch
deleted file mode 100644 (file)
index 578d5ae..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-From 178fdfff69b384c6f6ee2119bdfc4f3b945c162c Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 18 Oct 2023 09:39:15 -0700
-Subject: tools: ynl-gen: track attribute use
-
-From: Jakub Kicinski <kuba@kernel.org>
-
-[ Upstream commit ee0a4cfcbdcc6a7b2b35dba475e68187ebdafbf1 ]
-
-For range validation we'll need to know if any individual
-attribute is used on input (i.e. whether we will generate
-a policy for it). Track this information.
-
-Link: https://lore.kernel.org/r/20231018163917.2514503-2-kuba@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Stable-dep-of: ce6cb8113c84 ("tools: ynl-gen: individually free previous values on double set")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/net/ynl/ynl-gen-c.py | 20 ++++++++++++++++++++
- 1 file changed, 20 insertions(+)
-
-diff --git a/tools/net/ynl/ynl-gen-c.py b/tools/net/ynl/ynl-gen-c.py
-index 575b7e248e521..4c86fe0cd1179 100755
---- a/tools/net/ynl/ynl-gen-c.py
-+++ b/tools/net/ynl/ynl-gen-c.py
-@@ -42,6 +42,9 @@ class Type(SpecAttr):
-         self.type = attr['type']
-         self.checks = attr.get('checks', {})
-+        self.request = False
-+        self.reply = False
-+
-         if 'len' in attr:
-             self.len = attr['len']
-         if 'nested-attributes' in attr:
-@@ -845,6 +848,7 @@ class Family(SpecFamily):
-         self._load_root_sets()
-         self._load_nested_sets()
-+        self._load_attr_use()
-         self._load_hooks()
-         self.kernel_policy = self.yaml.get('kernel-policy', 'split')
-@@ -965,6 +969,22 @@ class Family(SpecFamily):
-                         child.request |= struct.request
-                         child.reply |= struct.reply
-+    def _load_attr_use(self):
-+        for _, struct in self.pure_nested_structs.items():
-+            if struct.request:
-+                for _, arg in struct.member_list():
-+                    arg.request = True
-+            if struct.reply:
-+                for _, arg in struct.member_list():
-+                    arg.reply = True
-+
-+        for root_set, rs_members in self.root_sets.items():
-+            for attr, spec in self.attr_sets[root_set].items():
-+                if attr in rs_members['request']:
-+                    spec.request = True
-+                if attr in rs_members['reply']:
-+                    spec.reply = True
-+
-     def _load_global_policy(self):
-         global_set = set()
-         attr_set_name = None
--- 
-2.39.5
-