diff options
-rw-r--r-- | drivers/net/macvlan.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 53422ce26f7f..59c315556a30 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c | |||
@@ -37,6 +37,7 @@ struct macvlan_port { | |||
37 | struct net_device *dev; | 37 | struct net_device *dev; |
38 | struct hlist_head vlan_hash[MACVLAN_HASH_SIZE]; | 38 | struct hlist_head vlan_hash[MACVLAN_HASH_SIZE]; |
39 | struct list_head vlans; | 39 | struct list_head vlans; |
40 | struct rcu_head rcu; | ||
40 | }; | 41 | }; |
41 | 42 | ||
42 | static struct macvlan_dev *macvlan_hash_lookup(const struct macvlan_port *port, | 43 | static struct macvlan_dev *macvlan_hash_lookup(const struct macvlan_port *port, |
@@ -540,14 +541,21 @@ static int macvlan_port_create(struct net_device *dev) | |||
540 | return err; | 541 | return err; |
541 | } | 542 | } |
542 | 543 | ||
544 | static void macvlan_port_rcu_free(struct rcu_head *head) | ||
545 | { | ||
546 | struct macvlan_port *port; | ||
547 | |||
548 | port = container_of(head, struct macvlan_port, rcu); | ||
549 | kfree(port); | ||
550 | } | ||
551 | |||
543 | static void macvlan_port_destroy(struct net_device *dev) | 552 | static void macvlan_port_destroy(struct net_device *dev) |
544 | { | 553 | { |
545 | struct macvlan_port *port = dev->macvlan_port; | 554 | struct macvlan_port *port = dev->macvlan_port; |
546 | 555 | ||
547 | netdev_rx_handler_unregister(dev); | 556 | netdev_rx_handler_unregister(dev); |
548 | rcu_assign_pointer(dev->macvlan_port, NULL); | 557 | rcu_assign_pointer(dev->macvlan_port, NULL); |
549 | synchronize_rcu(); | 558 | call_rcu(&port->rcu, macvlan_port_rcu_free); |
550 | kfree(port); | ||
551 | } | 559 | } |
552 | 560 | ||
553 | static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[]) | 561 | static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[]) |