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

net: dsa: allocate ports on touch

Allocate the struct dsa_port the first time it is accessed with
dsa_port_touch, and remove the static dsa_port array from the
dsa_switch structure.

Signed-off-by: Vivien Didelot <vivien.didelot@gmail.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>

authored by

Vivien Didelot and committed by
Jakub Kicinski
05f294a8 d5a619bf

+14 -4
-2
include/net/dsa.h
··· 277 277 */ 278 278 bool vlan_filtering; 279 279 280 - /* Dynamically allocated ports, keep last */ 281 280 size_t num_ports; 282 - struct dsa_port ports[]; 283 281 }; 284 282 285 283 static inline struct dsa_port *dsa_to_port(struct dsa_switch *ds, int p)
+14 -2
net/dsa/dsa2.c
··· 588 588 struct dsa_switch_tree *dst = ds->dst; 589 589 struct dsa_port *dp; 590 590 591 - dp = &ds->ports[index]; 591 + list_for_each_entry(dp, &dst->ports, list) 592 + if (dp->ds == ds && dp->index == index) 593 + return dp; 594 + 595 + dp = kzalloc(sizeof(*dp), GFP_KERNEL); 596 + if (!dp) 597 + return NULL; 592 598 593 599 dp->ds = ds; 594 600 dp->index = index; ··· 863 857 { 864 858 struct dsa_switch *ds; 865 859 866 - ds = devm_kzalloc(dev, struct_size(ds, ports, n), GFP_KERNEL); 860 + ds = devm_kzalloc(dev, sizeof(*ds), GFP_KERNEL); 867 861 if (!ds) 868 862 return NULL; 869 863 ··· 891 885 { 892 886 struct dsa_switch_tree *dst = ds->dst; 893 887 unsigned int index = ds->index; 888 + struct dsa_port *dp, *next; 889 + 890 + list_for_each_entry_safe(dp, next, &dst->ports, list) { 891 + list_del(&dp->list); 892 + kfree(dp); 893 + } 894 894 895 895 dsa_tree_remove_switch(dst, index); 896 896 }