netdev: Add addr_list_lock to struct net_device.
[deliverable/linux.git] / net / core / dev.c
index 0218b0b9be80ae030ea3c2381affe4c56a4a29c7..d933d1bfa6fa0c6ca1d704fe15be934657294715 100644 (file)
@@ -258,7 +258,7 @@ DEFINE_PER_CPU(struct softnet_data, softnet_data);
 
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 /*
- * register_netdevice() inits dev->_xmit_lock and sets lockdep class
+ * register_netdevice() inits txq->_xmit_lock and sets lockdep class
  * according to dev->type
  */
 static const unsigned short netdev_lock_type[] =
@@ -1758,19 +1758,19 @@ gso:
        if (dev->flags & IFF_UP) {
                int cpu = smp_processor_id(); /* ok because BHs are off */
 
-               if (dev->xmit_lock_owner != cpu) {
+               if (txq->xmit_lock_owner != cpu) {
 
-                       HARD_TX_LOCK(dev, cpu);
+                       HARD_TX_LOCK(dev, txq, cpu);
 
                        if (!netif_queue_stopped(dev) &&
                            !netif_subqueue_stopped(dev, skb)) {
                                rc = 0;
                                if (!dev_hard_start_xmit(skb, dev)) {
-                                       HARD_TX_UNLOCK(dev);
+                                       HARD_TX_UNLOCK(dev, txq);
                                        goto out;
                                }
                        }
-                       HARD_TX_UNLOCK(dev);
+                       HARD_TX_UNLOCK(dev, txq);
                        if (net_ratelimit())
                                printk(KERN_CRIT "Virtual device %s asks to "
                                       "queue packet!\n", dev->name);
@@ -2068,6 +2068,33 @@ out:
 }
 #endif
 
+/*
+ *     netif_nit_deliver - deliver received packets to network taps
+ *     @skb: buffer
+ *
+ *     This function is used to deliver incoming packets to network
+ *     taps. It should be used when the normal netif_receive_skb path
+ *     is bypassed, for example because of VLAN acceleration.
+ */
+void netif_nit_deliver(struct sk_buff *skb)
+{
+       struct packet_type *ptype;
+
+       if (list_empty(&ptype_all))
+               return;
+
+       skb_reset_network_header(skb);
+       skb_reset_transport_header(skb);
+       skb->mac_len = skb->network_header - skb->mac_header;
+
+       rcu_read_lock();
+       list_for_each_entry_rcu(ptype, &ptype_all, list) {
+               if (!ptype->dev || ptype->dev == skb->dev)
+                       deliver_skb(skb, ptype, skb->dev);
+       }
+       rcu_read_unlock();
+}
+
 /**
  *     netif_receive_skb - process receive buffer from network
  *     @skb: buffer to process
@@ -3761,6 +3788,20 @@ static void rollback_registered(struct net_device *dev)
        dev_put(dev);
 }
 
+static void __netdev_init_queue_locks_one(struct netdev_queue *dev_queue,
+                                         struct net_device *dev)
+{
+       spin_lock_init(&dev_queue->_xmit_lock);
+       netdev_set_lockdep_class(&dev_queue->_xmit_lock, dev->type);
+       dev_queue->xmit_lock_owner = -1;
+}
+
+static void netdev_init_queue_locks(struct net_device *dev)
+{
+       __netdev_init_queue_locks_one(&dev->tx_queue, dev);
+       __netdev_init_queue_locks_one(&dev->rx_queue, dev);
+}
+
 /**
  *     register_netdevice      - register a network device
  *     @dev: device to register
@@ -3795,9 +3836,8 @@ int register_netdevice(struct net_device *dev)
        BUG_ON(!dev_net(dev));
        net = dev_net(dev);
 
-       spin_lock_init(&dev->_xmit_lock);
-       netdev_set_lockdep_class(&dev->_xmit_lock, dev->type);
-       dev->xmit_lock_owner = -1;
+       spin_lock_init(&dev->addr_list_lock);
+       netdev_init_queue_locks(dev);
 
        dev->iflink = -1;
 
This page took 0.028502 seconds and 5 git commands to generate.