Skip to content

Commit

Permalink
vrf: remove slave queue and private slave struct
Browse files Browse the repository at this point in the history
The private slave queue and slave struct haven't been used for anything
and aren't needed, this allows to reduce memory usage and simplify
enslave/release. We can use netdev_for_each_lower_dev() to free the vrf
ports when deleting a vrf device. Also if in the future a private struct
is needed for each slave, it can be implemented via lower devices'
private member (similar to how bonding does it).

Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Nikolay Aleksandrov authored and davem330 committed Nov 24, 2015
1 parent 54f1aa2 commit bad5316
Showing 1 changed file with 5 additions and 63 deletions.
68 changes: 5 additions & 63 deletions drivers/net/vrf.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,7 @@
#define vrf_master_get_rcu(dev) \
((struct net_device *)rcu_dereference(dev->rx_handler_data))

struct slave {
struct list_head list;
struct net_device *dev;
};

struct slave_queue {
struct list_head all_slaves;
};

struct net_vrf {
struct slave_queue queue;
struct rtable *rth;
struct rt6_info *rt6;
u32 tb_id;
Expand Down Expand Up @@ -621,42 +611,9 @@ static void cycle_netdev(struct net_device *dev)
}
}

static struct slave *__vrf_find_slave_dev(struct slave_queue *queue,
struct net_device *dev)
{
struct list_head *head = &queue->all_slaves;
struct slave *slave;

list_for_each_entry(slave, head, list) {
if (slave->dev == dev)
return slave;
}

return NULL;
}

/* inverse of __vrf_insert_slave */
static void __vrf_remove_slave(struct slave_queue *queue, struct slave *slave)
{
list_del(&slave->list);
}

static void __vrf_insert_slave(struct slave_queue *queue, struct slave *slave)
{
list_add(&slave->list, &queue->all_slaves);
}

static int do_vrf_add_slave(struct net_device *dev, struct net_device *port_dev)
{
struct slave *slave = kzalloc(sizeof(*slave), GFP_KERNEL);
struct net_vrf *vrf = netdev_priv(dev);
struct slave_queue *queue = &vrf->queue;
int ret = -ENOMEM;

if (!slave)
goto out_fail;

slave->dev = port_dev;
int ret;

/* register the packet handler for slave ports */
ret = netdev_rx_handler_register(port_dev, vrf_handle_frame, dev);
Expand All @@ -672,15 +629,13 @@ static int do_vrf_add_slave(struct net_device *dev, struct net_device *port_dev)
goto out_unregister;

port_dev->priv_flags |= IFF_L3MDEV_SLAVE;
__vrf_insert_slave(queue, slave);
cycle_netdev(port_dev);

return 0;

out_unregister:
netdev_rx_handler_unregister(port_dev);
out_fail:
kfree(slave);
return ret;
}

Expand All @@ -695,23 +650,13 @@ static int vrf_add_slave(struct net_device *dev, struct net_device *port_dev)
/* inverse of do_vrf_add_slave */
static int do_vrf_del_slave(struct net_device *dev, struct net_device *port_dev)
{
struct net_vrf *vrf = netdev_priv(dev);
struct slave_queue *queue = &vrf->queue;
struct slave *slave;

netdev_upper_dev_unlink(port_dev, dev);
port_dev->priv_flags &= ~IFF_L3MDEV_SLAVE;

netdev_rx_handler_unregister(port_dev);

cycle_netdev(port_dev);

slave = __vrf_find_slave_dev(queue, port_dev);
if (slave)
__vrf_remove_slave(queue, slave);

kfree(slave);

return 0;
}

Expand All @@ -723,15 +668,14 @@ static int vrf_del_slave(struct net_device *dev, struct net_device *port_dev)
static void vrf_dev_uninit(struct net_device *dev)
{
struct net_vrf *vrf = netdev_priv(dev);
struct slave_queue *queue = &vrf->queue;
struct list_head *head = &queue->all_slaves;
struct slave *slave, *next;
struct net_device *port_dev;
struct list_head *iter;

vrf_rtable_destroy(vrf);
vrf_rt6_destroy(vrf);

list_for_each_entry_safe(slave, next, head, list)
vrf_del_slave(dev, slave->dev);
netdev_for_each_lower_dev(dev, port_dev, iter)
vrf_del_slave(dev, port_dev);

free_percpu(dev->dstats);
dev->dstats = NULL;
Expand All @@ -741,8 +685,6 @@ static int vrf_dev_init(struct net_device *dev)
{
struct net_vrf *vrf = netdev_priv(dev);

INIT_LIST_HEAD(&vrf->queue.all_slaves);

dev->dstats = netdev_alloc_pcpu_stats(struct pcpu_dstats);
if (!dev->dstats)
goto out_nomem;
Expand Down

0 comments on commit bad5316

Please sign in to comment.