]> 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 f861555cc5259332dbc8a5ca6baa9672616bef42..0879f52115eb9bada2f73bb3de2188ef9bf9a910 100644 (file)
 #include <linux/ctype.h>
 #include <linux/if_arp.h>
 
+#include "net-sysfs.h"
+
 /*
  *     The list of packet types we will receive (as opposed to discard)
  *     and the routines to invoke.
@@ -249,10 +251,6 @@ static RAW_NOTIFIER_HEAD(netdev_chain);
 
 DEFINE_PER_CPU(struct softnet_data, softnet_data);
 
-extern int netdev_kobject_init(void);
-extern int netdev_register_kobject(struct net_device *);
-extern void netdev_unregister_kobject(struct net_device *);
-
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 /*
  * register_netdevice() inits dev->_xmit_lock and sets lockdep class
@@ -885,6 +883,9 @@ int dev_change_name(struct net_device *dev, char *newname)
        if (!dev_valid_name(newname))
                return -EINVAL;
 
+       if (strncmp(newname, dev->name, IFNAMSIZ) == 0)
+               return 0;
+
        memcpy(oldname, dev->name, IFNAMSIZ);
 
        if (strchr(newname, '%')) {
@@ -1170,6 +1171,8 @@ rollback:
                        nb->notifier_call(nb, NETDEV_UNREGISTER, dev);
                }
        }
+
+       raw_notifier_chain_unregister(&netdev_chain, nb);
        goto unlock;
 }
 
@@ -1750,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)
  *
  */
@@ -2000,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;
@@ -2171,7 +2186,15 @@ static void net_rx_action(struct softirq_action *h)
 
                weight = n->weight;
 
-               work = n->poll(n, weight);
+               /* This NAPI_STATE_SCHED test is for avoiding a race
+                * with netpoll's poll_napi().  Only the entity which
+                * obtains the lock and sees NAPI_STATE_SCHED set will
+                * actually make the ->poll() call.  Therefore we avoid
+                * accidently calling ->poll() when NAPI is not scheduled.
+                */
+               work = 0;
+               if (test_bit(NAPI_STATE_SCHED, &n->state))
+                       work = n->poll(n, weight);
 
                WARN_ON_ONCE(work > weight);
 
@@ -2184,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);
        }
@@ -2796,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)
@@ -3487,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
@@ -3624,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;
@@ -3893,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.
@@ -3902,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);
 }
 
 /**
@@ -3962,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
@@ -4303,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)