From: Ben Pfaff Date: Mon, 21 Jul 2008 18:22:28 +0000 (-0700) Subject: Properly synchronize dp_dev destruction. X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=d50ae013a29dceadb205b93bc4c1fbf3c2dea120;p=sliver-openvswitch.git Properly synchronize dp_dev destruction. Before, we didn't really synchronize this at all. Now, when we want to destroy the ofX device, we stop the transmit path and wait for in-progress transmissions to finish. --- diff --git a/datapath/dp_dev.c b/datapath/dp_dev.c index e618d7188..02468eb48 100644 --- a/datapath/dp_dev.c +++ b/datapath/dp_dev.c @@ -55,19 +55,16 @@ static int dp_dev_mac_addr(struct net_device *dev, void *p) static int dp_dev_xmit(struct sk_buff *skb, struct net_device *netdev) { struct dp_dev *dp_dev = dp_dev_priv(netdev); - struct datapath *dp; + struct datapath *dp = dp_dev->dp; + + dp_dev->stats.tx_packets++; + dp_dev->stats.tx_bytes += skb->len; + + skb_reset_mac_header(skb); rcu_read_lock(); - dp = dp_dev->dp; - if (likely(dp != NULL)) { - dp_dev->stats.tx_packets++; - dp_dev->stats.tx_bytes += skb->len; - skb_reset_mac_header(skb); - fwd_port_input(dp->chain, skb, OFPP_LOCAL); - } else { - dp_dev->stats.tx_dropped++; - kfree_skb(skb); - } + fwd_port_input(dp->chain, skb, OFPP_LOCAL); rcu_read_unlock(); + return 0; } @@ -127,8 +124,7 @@ int dp_dev_setup(struct datapath *dp) void dp_dev_destroy(struct datapath *dp) { - struct dp_dev *dp_dev = dp_dev_priv(dp->netdev); - dp_dev->dp = NULL; + netif_tx_disable(dp->netdev); synchronize_net(); unregister_netdev(dp->netdev); free_netdev(dp->netdev);