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

tools: ynl-gen: move the count into a presence struct too

While we reshuffle the presence members, move the counts as well.
Previously array count members would have been place directly in
the struct, so:

struct family_op_req {
struct {
u32 a:1;
u32 b:1;
} _present;
struct {
u32 bin;
} _len;

u32 a;
u64 b;
const unsigned char *bin;
u32 n_multi; << count
u32 *multi; << objects
};

Since len has been moved to its own presence struct move the count
as well:

struct family_op_req {
struct {
u32 a:1;
u32 b:1;
} _present;
struct {
u32 bin;
} _len;
struct {
u32 multi; << count
} _count;

u32 a;
u64 b;
const unsigned char *bin;
u32 *multi; << objects
};

This improves the consistency and allows us to remove some hacks
in the codegen. Unlike for len there is no known name collision
with the existing scheme.

Link: https://patch.msgid.link/20250505165208.248049-4-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+16 -21
+13 -19
tools/net/ynl/pyynl/ynl_gen_c.py
··· 152 152 pfx = '__' if space == 'user' else '' 153 153 return f"{pfx}u32 {self.c_name}:1;" 154 154 155 - if self.presence_type() == 'len': 155 + if self.presence_type() in {'len', 'count'}: 156 156 pfx = '__' if space == 'user' else '' 157 157 return f"{pfx}u32 {self.c_name};" 158 158 ··· 185 185 def struct_member(self, ri): 186 186 member = self._complex_member_type(ri) 187 187 if member: 188 - if self.is_multi_val(): 189 - ri.cw.p(f"unsigned int n_{self.c_name};") 190 188 ptr = '*' if self.is_multi_val() else '' 191 189 if self.is_recursive_for_op(ri): 192 190 ptr = '*' ··· 676 678 lines += [f"free({var}->{ref}{self.c_name});"] 677 679 elif self.attr['type'] == 'string': 678 680 lines += [ 679 - f"for (i = 0; i < {var}->{ref}n_{self.c_name}; i++)", 681 + f"for (i = 0; i < {var}->{ref}_count.{self.c_name}; i++)", 680 682 f"free({var}->{ref}{self.c_name}[i]);", 681 683 f"free({var}->{ref}{self.c_name});", 682 684 ] 683 685 elif 'type' not in self.attr or self.attr['type'] == 'nest': 684 686 lines += [ 685 - f"for (i = 0; i < {var}->{ref}n_{self.c_name}; i++)", 687 + f"for (i = 0; i < {var}->{ref}_count.{self.c_name}; i++)", 686 688 f'{self.nested_render_name}_free(&{var}->{ref}{self.c_name}[i]);', 687 689 f"free({var}->{ref}{self.c_name});", 688 690 ] ··· 702 704 def attr_put(self, ri, var): 703 705 if self.attr['type'] in scalars: 704 706 put_type = self.type 705 - ri.cw.p(f"for (i = 0; i < {var}->n_{self.c_name}; i++)") 707 + ri.cw.p(f"for (i = 0; i < {var}->_count.{self.c_name}; i++)") 706 708 ri.cw.p(f"ynl_attr_put_{put_type}(nlh, {self.enum_name}, {var}->{self.c_name}[i]);") 707 709 elif self.attr['type'] == 'binary' and 'struct' in self.attr: 708 - ri.cw.p(f"for (i = 0; i < {var}->n_{self.c_name}; i++)") 710 + ri.cw.p(f"for (i = 0; i < {var}->_count.{self.c_name}; i++)") 709 711 ri.cw.p(f"ynl_attr_put(nlh, {self.enum_name}, &{var}->{self.c_name}[i], sizeof(struct {c_lower(self.attr['struct'])}));") 710 712 elif self.attr['type'] == 'string': 711 - ri.cw.p(f"for (i = 0; i < {var}->n_{self.c_name}; i++)") 713 + ri.cw.p(f"for (i = 0; i < {var}->_count.{self.c_name}; i++)") 712 714 ri.cw.p(f"ynl_attr_put_str(nlh, {self.enum_name}, {var}->{self.c_name}[i]->str);") 713 715 elif 'type' not in self.attr or self.attr['type'] == 'nest': 714 - ri.cw.p(f"for (i = 0; i < {var}->n_{self.c_name}; i++)") 716 + ri.cw.p(f"for (i = 0; i < {var}->_count.{self.c_name}; i++)") 715 717 self._attr_put_line(ri, var, f"{self.nested_render_name}_put(nlh, " + 716 718 f"{self.enum_name}, &{var}->{self.c_name}[i])") 717 719 else: 718 720 raise Exception(f"Put of MultiAttr sub-type {self.attr['type']} not supported yet") 719 721 720 722 def _setter_lines(self, ri, member, presence): 721 - # For multi-attr we have a count, not presence, hack up the presence 722 - presence = presence[:-(len('_count.') + len(self.c_name))] + "n_" + self.c_name 723 723 return [f"{member} = {self.c_name};", 724 724 f"{presence} = n_{self.c_name};"] 725 725 ··· 760 764 'ynl_attr_for_each_nested(attr2, attr) {', 761 765 '\tif (ynl_attr_validate(yarg, attr2))', 762 766 '\t\treturn YNL_PARSE_CB_ERROR;', 763 - f'\t{var}->n_{self.c_name}++;', 767 + f'\t{var}->_count.{self.c_name}++;', 764 768 '}'] 765 769 return get_lines, None, local_vars 766 770 ··· 768 772 ri.cw.p(f'array = ynl_attr_nest_start(nlh, {self.enum_name});') 769 773 if self.sub_type in scalars: 770 774 put_type = self.sub_type 771 - ri.cw.block_start(line=f'for (i = 0; i < {var}->n_{self.c_name}; i++)') 775 + ri.cw.block_start(line=f'for (i = 0; i < {var}->_count.{self.c_name}; i++)') 772 776 ri.cw.p(f"ynl_attr_put_{put_type}(nlh, i, {var}->{self.c_name}[i]);") 773 777 ri.cw.block_end() 774 778 elif self.sub_type == 'binary' and 'exact-len' in self.checks: 775 - ri.cw.p(f'for (i = 0; i < {var}->n_{self.c_name}; i++)') 779 + ri.cw.p(f'for (i = 0; i < {var}->_count.{self.c_name}; i++)') 776 780 ri.cw.p(f"ynl_attr_put(nlh, i, {var}->{self.c_name}[i], {self.checks['exact-len']});") 777 781 else: 778 782 raise Exception(f"Put for ArrayNest sub-type {self.attr['sub-type']} not supported, yet") 779 783 ri.cw.p('ynl_attr_nest_end(nlh, array);') 780 784 781 785 def _setter_lines(self, ri, member, presence): 782 - # For multi-attr we have a count, not presence, hack up the presence 783 - presence = presence[:-(len('_count.') + len(self.c_name))] + "n_" + self.c_name 784 786 return [f"{member} = {self.c_name};", 785 787 f"{presence} = n_{self.c_name};"] 786 788 ··· 1878 1884 1879 1885 ri.cw.block_start(line=f"if (n_{aspec.c_name})") 1880 1886 ri.cw.p(f"dst->{aspec.c_name} = calloc(n_{aspec.c_name}, sizeof(*dst->{aspec.c_name}));") 1881 - ri.cw.p(f"dst->n_{aspec.c_name} = n_{aspec.c_name};") 1887 + ri.cw.p(f"dst->_count.{aspec.c_name} = n_{aspec.c_name};") 1882 1888 ri.cw.p('i = 0;') 1883 1889 if 'nested-attributes' in aspec: 1884 1890 ri.cw.p(f"parg.rsp_policy = &{aspec.nested_render_name}_nest;") ··· 1903 1909 aspec = struct[anest] 1904 1910 ri.cw.block_start(line=f"if (n_{aspec.c_name})") 1905 1911 ri.cw.p(f"dst->{aspec.c_name} = calloc(n_{aspec.c_name}, sizeof(*dst->{aspec.c_name}));") 1906 - ri.cw.p(f"dst->n_{aspec.c_name} = n_{aspec.c_name};") 1912 + ri.cw.p(f"dst->_count.{aspec.c_name} = n_{aspec.c_name};") 1907 1913 ri.cw.p('i = 0;') 1908 1914 if 'nested-attributes' in aspec: 1909 1915 ri.cw.p(f"parg.rsp_policy = &{aspec.nested_render_name}_nest;") ··· 2180 2186 ri.cw.p(ri.fixed_hdr + ' _hdr;') 2181 2187 ri.cw.nl() 2182 2188 2183 - for type_filter in ['present', 'len']: 2189 + for type_filter in ['present', 'len', 'count']: 2184 2190 meta_started = False 2185 2191 for _, attr in struct.member_list(): 2186 2192 line = attr.presence_member(ri.ku_space, type_filter)
+3 -2
tools/net/ynl/samples/devlink.c
··· 22 22 ynl_dump_foreach(devs, d) { 23 23 struct devlink_info_get_req *info_req; 24 24 struct devlink_info_get_rsp *info_rsp; 25 + unsigned i; 25 26 26 27 printf("%s/%s:\n", d->bus_name, d->dev_name); 27 28 ··· 37 36 38 37 if (info_rsp->_len.info_driver_name) 39 38 printf(" driver: %s\n", info_rsp->info_driver_name); 40 - if (info_rsp->n_info_version_running) 39 + if (info_rsp->_count.info_version_running) 41 40 printf(" running fw:\n"); 42 - for (unsigned i = 0; i < info_rsp->n_info_version_running; i++) 41 + for (i = 0; i < info_rsp->_count.info_version_running; i++) 43 42 printf(" %s: %s\n", 44 43 info_rsp->info_version_running[i].info_version_name, 45 44 info_rsp->info_version_running[i].info_version_value);