提交 0015b80a 编写于 作者: S Salvatore Mesoraca 提交者: David S. Miller

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.chSigned-off-by: NSalvatore Mesoraca <s.mesoraca16@gmail.com>
[kees: tweak commit subject and message slightly]
Signed-off-by: NKees Cook <keescook@chromium.org>
Reviewed-by: NAndrew Lunn <andrew@lunn.ch>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 14260e91
...@@ -259,6 +259,9 @@ struct dsa_switch { ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册