net: dsa: Remove VLA usage
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 Link: http://lkml.kernel.org/r/20180505185145.GB32630@lunn.ch Signed-off-by: Salvatore Mesoraca <s.mesoraca16@gmail.com> [kees: tweak commit subject and message slightly] Signed-off-by: Kees Cook <keescook@chromium.org> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
14260e9170
commit
0015b80abc
@ -259,6 +259,9 @@ struct dsa_switch {
|
|||||||
/* Number of switch port queues */
|
/* Number of switch port queues */
|
||||||
unsigned int num_tx_queues;
|
unsigned int num_tx_queues;
|
||||||
|
|
||||||
|
unsigned long *bitmap;
|
||||||
|
unsigned long _bitmap;
|
||||||
|
|
||||||
/* Dynamically allocated ports, keep last */
|
/* Dynamically allocated ports, keep last */
|
||||||
size_t num_ports;
|
size_t num_ports;
|
||||||
struct dsa_port ports[];
|
struct dsa_port ports[];
|
||||||
|
@ -775,6 +775,20 @@ struct dsa_switch *dsa_switch_alloc(struct device *dev, size_t n)
|
|||||||
if (!ds)
|
if (!ds)
|
||||||
return NULL;
|
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->dev = dev;
|
||||||
ds->num_ports = n;
|
ds->num_ports = n;
|
||||||
|
|
||||||
|
@ -136,21 +136,20 @@ static int dsa_switch_mdb_add(struct dsa_switch *ds,
|
|||||||
{
|
{
|
||||||
const struct switchdev_obj_port_mdb *mdb = info->mdb;
|
const struct switchdev_obj_port_mdb *mdb = info->mdb;
|
||||||
struct switchdev_trans *trans = info->trans;
|
struct switchdev_trans *trans = info->trans;
|
||||||
DECLARE_BITMAP(group, ds->num_ports);
|
|
||||||
int port;
|
int port;
|
||||||
|
|
||||||
/* Build a mask of Multicast group members */
|
/* 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)
|
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++)
|
for (port = 0; port < ds->num_ports; port++)
|
||||||
if (dsa_is_dsa_port(ds, port))
|
if (dsa_is_dsa_port(ds, port))
|
||||||
set_bit(port, group);
|
set_bit(port, ds->bitmap);
|
||||||
|
|
||||||
if (switchdev_trans_ph_prepare(trans))
|
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;
|
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;
|
const struct switchdev_obj_port_vlan *vlan = info->vlan;
|
||||||
struct switchdev_trans *trans = info->trans;
|
struct switchdev_trans *trans = info->trans;
|
||||||
DECLARE_BITMAP(members, ds->num_ports);
|
|
||||||
int port;
|
int port;
|
||||||
|
|
||||||
/* Build a mask of VLAN members */
|
/* 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)
|
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++)
|
for (port = 0; port < ds->num_ports; port++)
|
||||||
if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, 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))
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user