net: dsa: Remove VLA usage
Subsystems (3)
PATCH v2 1/1 net: dsa: Remove VLA usage
From: Salvatore Mesoraca <[email protected]>
We avoid 2 VLAs by using a pre-allocated field in dsa_switch. We also try to avoid dynamic allocation whenever possible (when using fewer than bits-per-long ports, which is the common case).
--- include/net/dsa.h | 3 +++ net/dsa/dsa2.c | 14 ++++++++++++++ net/dsa/switch.c | 22 ++++++++++------------ 3 files changed, 27 insertions(+), 12 deletions(-)
include/net/dsa.h +3 -0
@@ -259,6 +259,9 @@ struct dsa_switch {/* Number of switch port queues */ unsigned int num_tx_queues; +unsigned long *bitmap; +unsigned long _bitmap; +/* Dynamically allocated ports, keep last */ size_t num_ports;struct dsa_port ports[];
net/dsa/dsa2.c +14 -0
@@ -775,6 +775,20 @@ struct dsa_switch *dsa_switch_alloc(struct device *dev, size_t n)if (!ds)return NULL ; +/* We avoid allocating memory outside dsa_switch +* if it is not needed. +*/ +if (n <=sizeof (ds->_bitmap) *8 ) { + ds->bitmap = &ds->_bitmap; + }else { + ds->bitmap =devm_kcalloc (dev, +BITS_TO_LONGS (n), +sizeof (unsigned long ), +GFP_KERNEL ); +if (unlikely (!ds->bitmap)) +return NULL ; + } + ds->dev = dev; ds->num_ports = n;
net/dsa/switch.c +10 -12
@@ -136,21 +136,20 @@ static int dsa_switch_mdb_add(struct dsa_switch *ds, {const struct switchdev_obj_port_mdb *mdb = info->mdb;struct switchdev_trans *trans = info->trans; -DECLARE_BITMAP (group, ds->num_ports);int port;/* Build a mask of Multicast group members */ -bitmap_zero (group, ds->num_ports); +bitmap_zero (ds->bitmap, ds->num_ports);if (ds->index == info->sw_index) -set_bit (info->port, group); +set_bit (info->port, ds->bitmap);for (port =0 ; port < ds->num_ports; port++)if (dsa_is_dsa_port (ds, port)) -set_bit (port, group); +set_bit (port, ds->bitmap);if (switchdev_trans_ph_prepare (trans)) -return dsa_switch_mdb_prepare_bitmap (ds, mdb, group); +return dsa_switch_mdb_prepare_bitmap (ds, mdb, ds->bitmap); -dsa_switch_mdb_add_bitmap (ds, mdb, group); +dsa_switch_mdb_add_bitmap (ds, mdb, ds->bitmap);return 0 ; }
@@ -204,21 +203,20 @@ static int dsa_switch_vlan_add(struct dsa_switch *ds, {const struct switchdev_obj_port_vlan *vlan = info->vlan;struct switchdev_trans *trans = info->trans; -DECLARE_BITMAP (members, ds->num_ports);int port;/* Build a mask of VLAN members */ -bitmap_zero (members, ds->num_ports); +bitmap_zero (ds->bitmap, ds->num_ports);if (ds->index == info->sw_index) -set_bit (info->port, members); +set_bit (info->port, ds->bitmap);for (port =0 ; port < ds->num_ports; port++)if (dsa_is_cpu_port (ds, port) ||dsa_is_dsa_port (ds, port)) -set_bit (port, members); +set_bit (port, ds->bitmap);if (switchdev_trans_ph_prepare (trans)) -return dsa_switch_vlan_prepare_bitmap (ds, vlan, members); +return dsa_switch_vlan_prepare_bitmap (ds, vlan, ds->bitmap); -dsa_switch_vlan_add_bitmap (ds, vlan, members); +dsa_switch_vlan_add_bitmap (ds, vlan, ds->bitmap);return 0 ; }
Signature · 6 lines
2.17.1 -- Kees Cook Pixel Security
David Miller
maintainerFrom: Kees Cook <[email protected]>
Date: Mon, 16 Jul 2018 21:10:34 -0700
Quoted 11 lines
From: Salvatore Mesoraca <[email protected]>
We avoid 2 VLAs by using a pre-allocated field in
dsa_switch. We also try to avoid dynamic allocation whenever possible (when using fewer than bits-per-long ports, which is the common case).Link http://lkml.kernel.org/r/CA+55aFzCG-zNmZwX4A2FQpadafLfEzK6CC=qPXydAacU1RqZWA@mail.gmail.com open hereSigned-off-by Salvatore Mesoraca <[email protected]>[kees: tweak commit subject and message slightly]Signed-off-by Kees Cook <[email protected]>
Florian and Andrew, please review.
Quoted 9 lines · David Miller
From: Kees Cook <[email protected]>
Date: Mon, 16 Jul 2018 21:10:34 -0700Quoted 6 lines
From: Salvatore Mesoraca <[email protected]>
We avoid 2 VLAs by using a pre-allocated field in
dsa_switch. We also try to avoid dynamic allocation whenever possible (when using fewer than bits-per-long ports, which is the common case).
Quoted 7 lines
Quoted 5 lines
Link http://lkml.kernel.org/r/CA+55aFzCG-zNmZwX4A2FQpadafLfEzK6CC=qPXydAacU1RqZWA@mail.gmail.com open hereSigned-off-by Salvatore Mesoraca <[email protected]>[kees: tweak commit subject and message slightly]Signed-off-by Kees Cook <[email protected]>Florian and Andrew, please review.
Last time there was some discussion of just always allocating it to make the code simpler. But the extra complexity is O.K.
Andrew
David Miller
maintainerFrom: Andrew Lunn <[email protected]>
Date: Wed, 18 Jul 2018 22:37:25 +0200
Quoted 16 lines · David Miller
Quoted 15 lines
From: Kees Cook <[email protected]>
Date: Mon, 16 Jul 2018 21:10:34 -0700Quoted 11 lines
From: Salvatore Mesoraca <[email protected]>
We avoid 2 VLAs by using a pre-allocated field in
dsa_switch. We also try to avoid dynamic allocation whenever possible (when using fewer than bits-per-long ports, which is the common case).Link http://lkml.kernel.org/r/CA+55aFzCG-zNmZwX4A2FQpadafLfEzK6CC=qPXydAacU1RqZWA@mail.gmail.com open hereSigned-off-by Salvatore Mesoraca <[email protected]>[kees: tweak commit subject and message slightly]Signed-off-by Kees Cook <[email protected]>
Quoted 6 lines
Quoted 1 line
Florian and Andrew, please review.
Last time there was some discussion of just always allocating it to make the code simpler. But the extra complexity is O.K.
Reviewed-by Andrew Lunn <[email protected]>
Great, applied, thanks!
Hi!
Quoted 20 lines
We avoid 2 VLAs by using a pre-allocated field in
dsa_switch. We also try to avoid dynamic allocation whenever possible (when using fewer than bits-per-long ports, which is the common case).Link http://lkml.kernel.org/r/CA+55aFzCG-zNmZwX4A2FQpadafLfEzK6CC=qPXydAacU1RqZWA@mail.gmail.com open hereSigned-off-by Salvatore Mesoraca <[email protected]>[kees: tweak commit subject and message slightly]Signed-off-by Kees Cook <[email protected]>--- include/net/dsa.h | 3 +++ net/dsa/dsa2.c | 14 ++++++++++++++ net/dsa/switch.c | 22 ++++++++++------------ 3 files changed, 27 insertions(+), 12 deletions(-)include/net/dsa.h +0
-0
include/net/dsa.h struct dsa_switch { · line 263
Quoted 5 lines
include/net/dsa.h +2
-0@@ -259,6 +259,9 @@ struct dsa_switch {/* Number of switch port queues */ unsigned int num_tx_queues; +unsigned long *bitmap; +unsigned long _bitmap;
This looks rather confusing. _bitmap -> bitmap_data? bitmap_bits?
Thanks,
Pavel
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
Hi!
Quoted 23 lines
Quoted 23 lines
We avoid 2 VLAs by using a pre-allocated field in
dsa_switch. We also try to avoid dynamic allocation whenever possible (when using fewer than bits-per-long ports, which is the common case).Link http://lkml.kernel.org/r/CA+55aFzCG-zNmZwX4A2FQpadafLfEzK6CC=qPXydAacU1RqZWA@mail.gmail.com open hereSigned-off-by Salvatore Mesoraca <[email protected]>[kees: tweak commit subject and message slightly]Signed-off-by Kees Cook <[email protected]>--- include/net/dsa.h | 3 +++ net/dsa/dsa2.c | 14 ++++++++++++++ net/dsa/switch.c | 22 ++++++++++------------ 3 files changed, 27 insertions(+), 12 deletions(-)include/net/dsa.h +0
-0@@ -259,6 +259,9 @@ struct dsa_switch {/* Number of switch port queues */ unsigned int num_tx_queues;
Quoted 4 lines
include/net/dsa.h struct dsa_switch { · line 263
Quoted 2 lines
include/net/dsa.h +2
-0+unsigned long *bitmap; +unsigned long _bitmap;This looks rather confusing.
_bitmap->bitmap_data?bitmap_bits?
Actually, AFAICT that long is not used as a long, but as array of bits. So maybe char bitmap_data[8] would be more appropriate?
(resend, now with right cc list).
Pavel
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
From: Pavel Machek
Quoted 1 line
Sent: 29 July 2018 12:40
...
Quoted 7 lines
Quoted 4 lines
include/net/dsa.h struct dsa_switch { · line 263
Quoted 2 lines
include/net/dsa.h +2
-0+unsigned long *bitmap; +unsigned long _bitmap;This looks rather confusing.
_bitmap->bitmap_data?bitmap_bits?Actually, AFAICT that long is not used as a long, but as array of bits. So maybe char bitmap_data[8] would be more appropriate?
Unfortunately the 'bitmap' functions are defined to work in a specific way on unsigned long[].
This means, for example, that they can't use the x86 'bit' instructions.
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)