]> err.no Git - linux-2.6/blobdiff - net/core/dev.c
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfashe...
[linux-2.6] / net / core / dev.c
index 02e7d8377c4a2b33abf1cfb9a00d83fad16d26ed..0879f52115eb9bada2f73bb3de2188ef9bf9a910 100644 (file)
@@ -1171,6 +1171,8 @@ rollback:
                        nb->notifier_call(nb, NETDEV_UNREGISTER, dev);
                }
        }
+
+       raw_notifier_chain_unregister(&netdev_chain, nb);
        goto unlock;
 }
 
@@ -1751,9 +1753,6 @@ DEFINE_PER_CPU(struct netif_rx_stats, netdev_rx_stat) = { 0, };
  *
  *     return values:
  *     NET_RX_SUCCESS  (no congestion)
- *     NET_RX_CN_LOW   (low congestion)
- *     NET_RX_CN_MOD   (moderate congestion)
- *     NET_RX_CN_HIGH  (high congestion)
  *     NET_RX_DROP     (packet was dropped)
  *
  */
@@ -2001,6 +2000,21 @@ out:
 }
 #endif
 
+/**
+ *     netif_receive_skb - process receive buffer from network
+ *     @skb: buffer to process
+ *
+ *     netif_receive_skb() is the main receive data processing function.
+ *     It always succeeds. The buffer may be dropped during processing
+ *     for congestion control or by the protocol layers.
+ *
+ *     This function may only be called from softirq context and interrupts
+ *     should be enabled.
+ *
+ *     Return values (usually ignored):
+ *     NET_RX_SUCCESS: no congestion
+ *     NET_RX_DROP: packet was dropped
+ */
 int netif_receive_skb(struct sk_buff *skb)
 {
        struct packet_type *ptype, *pt_prev;
@@ -2193,8 +2207,12 @@ static void net_rx_action(struct softirq_action *h)
                 * still "owns" the NAPI instance and therefore can
                 * move the instance around on the list at-will.
                 */
-               if (unlikely(work == weight))
-                       list_move_tail(&n->poll_list, list);
+               if (unlikely(work == weight)) {
+                       if (unlikely(napi_disable_pending(n)))
+                               __napi_complete(n);
+                       else
+                               list_move_tail(&n->poll_list, list);
+               }
 
                netpoll_poll_unlock(have);
        }
@@ -2676,7 +2694,7 @@ static void __net_exit dev_proc_net_exit(struct net *net)
        proc_net_remove(net, "dev");
 }
 
-static struct pernet_operations dev_proc_ops = {
+static struct pernet_operations __net_initdata dev_proc_ops = {
        .init = dev_proc_net_init,
        .exit = dev_proc_net_exit,
 };
@@ -2805,7 +2823,7 @@ void dev_set_allmulti(struct net_device *dev, int inc)
 /*
  *     Upload unicast and multicast address lists to device and
  *     configure RX filtering. When the device doesn't support unicast
- *     filtering it is put in promiscous mode while unicast addresses
+ *     filtering it is put in promiscuous mode while unicast addresses
  *     are present.
  */
 void __dev_set_rx_mode(struct net_device *dev)
@@ -3496,6 +3514,60 @@ static void net_set_todo(struct net_device *dev)
        spin_unlock(&net_todo_list_lock);
 }
 
+static void rollback_registered(struct net_device *dev)
+{
+       BUG_ON(dev_boot_phase);
+       ASSERT_RTNL();
+
+       /* Some devices call without registering for initialization unwind. */
+       if (dev->reg_state == NETREG_UNINITIALIZED) {
+               printk(KERN_DEBUG "unregister_netdevice: device %s/%p never "
+                                 "was registered\n", dev->name, dev);
+
+               WARN_ON(1);
+               return;
+       }
+
+       BUG_ON(dev->reg_state != NETREG_REGISTERED);
+
+       /* If device is running, close it first. */
+       dev_close(dev);
+
+       /* And unlink it from device chain. */
+       unlist_netdevice(dev);
+
+       dev->reg_state = NETREG_UNREGISTERING;
+
+       synchronize_net();
+
+       /* Shutdown queueing discipline. */
+       dev_shutdown(dev);
+
+
+       /* Notify protocols, that we are about to destroy
+          this device. They should clean all the things.
+       */
+       call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
+
+       /*
+        *      Flush the unicast and multicast chains
+        */
+       dev_addr_discard(dev);
+
+       if (dev->uninit)
+               dev->uninit(dev);
+
+       /* Notifier chain MUST detach us from master device. */
+       BUG_TRAP(!dev->master);
+
+       /* Remove entries from kobject tree */
+       netdev_unregister_kobject(dev);
+
+       synchronize_net();
+
+       dev_put(dev);
+}
+
 /**
  *     register_netdevice      - register a network device
  *     @dev: device to register
@@ -3633,8 +3705,10 @@ int register_netdevice(struct net_device *dev)
        /* Notify protocols, that a new device appeared. */
        ret = call_netdevice_notifiers(NETDEV_REGISTER, dev);
        ret = notifier_to_errno(ret);
-       if (ret)
-               unregister_netdevice(dev);
+       if (ret) {
+               rollback_registered(dev);
+               dev->reg_state = NETREG_UNREGISTERED;
+       }
 
 out:
        return ret;
@@ -3902,8 +3976,7 @@ void synchronize_net(void)
  *     @dev: device
  *
  *     This function shuts down a device interface and removes it
- *     from the kernel tables. On success 0 is returned, on a failure
- *     a negative errno code is returned.
+ *     from the kernel tables.
  *
  *     Callers must hold the rtnl semaphore.  You may want
  *     unregister_netdev() instead of this.
@@ -3911,59 +3984,9 @@ void synchronize_net(void)
 
 void unregister_netdevice(struct net_device *dev)
 {
-       BUG_ON(dev_boot_phase);
-       ASSERT_RTNL();
-
-       /* Some devices call without registering for initialization unwind. */
-       if (dev->reg_state == NETREG_UNINITIALIZED) {
-               printk(KERN_DEBUG "unregister_netdevice: device %s/%p never "
-                                 "was registered\n", dev->name, dev);
-
-               WARN_ON(1);
-               return;
-       }
-
-       BUG_ON(dev->reg_state != NETREG_REGISTERED);
-
-       /* If device is running, close it first. */
-       dev_close(dev);
-
-       /* And unlink it from device chain. */
-       unlist_netdevice(dev);
-
-       dev->reg_state = NETREG_UNREGISTERING;
-
-       synchronize_net();
-
-       /* Shutdown queueing discipline. */
-       dev_shutdown(dev);
-
-
-       /* Notify protocols, that we are about to destroy
-          this device. They should clean all the things.
-       */
-       call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
-
-       /*
-        *      Flush the unicast and multicast chains
-        */
-       dev_addr_discard(dev);
-
-       if (dev->uninit)
-               dev->uninit(dev);
-
-       /* Notifier chain MUST detach us from master device. */
-       BUG_TRAP(!dev->master);
-
-       /* Remove entries from kobject tree */
-       netdev_unregister_kobject(dev);
-
+       rollback_registered(dev);
        /* Finish processing unregister after unlock */
        net_set_todo(dev);
-
-       synchronize_net();
-
-       dev_put(dev);
 }
 
 /**
@@ -3971,8 +3994,7 @@ void unregister_netdevice(struct net_device *dev)
  *     @dev: device
  *
  *     This function shuts down a device interface and removes it
- *     from the kernel tables. On success 0 is returned, on a failure
- *     a negative errno code is returned.
+ *     from the kernel tables.
  *
  *     This is just a wrapper for unregister_netdevice that takes
  *     the rtnl semaphore.  In general you want to use this and not
@@ -4312,7 +4334,6 @@ static struct hlist_head *netdev_create_hash(void)
 static int __net_init netdev_init(struct net *net)
 {
        INIT_LIST_HEAD(&net->dev_base_head);
-       rwlock_init(&dev_base_lock);
 
        net->dev_name_head = netdev_create_hash();
        if (net->dev_name_head == NULL)
@@ -4336,7 +4357,7 @@ static void __net_exit netdev_exit(struct net *net)
        kfree(net->dev_index_head);
 }
 
-static struct pernet_operations  netdev_net_ops = {
+static struct pernet_operations __net_initdata netdev_net_ops = {
        .init = netdev_init,
        .exit = netdev_exit,
 };
@@ -4367,7 +4388,7 @@ static void __net_exit default_device_exit(struct net *net)
        rtnl_unlock();
 }
 
-static struct pernet_operations  default_device_ops = {
+static struct pernet_operations __net_initdata default_device_ops = {
        .exit = default_device_exit,
 };