]> git.neil.brown.name Git - history.git/commitdiff
[NET]: Loopback device simplification.
authorStephen Hemminger <shemminger@osdl.org>
Wed, 3 Sep 2003 17:41:35 +0000 (10:41 -0700)
committerStephen Hemminger <shemminger@osdl.org>
Wed, 3 Sep 2003 17:41:35 +0000 (10:41 -0700)
Now that all the magic chain of static devices is gone from Space.c
The initialization of the one remaining static device (ie the loopback driver)
can be simplified.

One small change was to reduce possibility of failing the initialization if
allocation of private data failed by just going without statistics.

drivers/net/Space.c
drivers/net/loopback.c
net/core/dev.c

index a8a92838db2672944ee9c3c261b9d7c9377bb475..470cae32a543dc4e941d39acaa9d7e5f4e40ce1c 100644 (file)
@@ -39,9 +39,6 @@
 #include <linux/netlink.h>
 #include <linux/divert.h>
 
-#define        NEXT_DEV        NULL
-
-
 /* A unified ethernet device probe.  This is the easiest way to have every
    ethernet adaptor have the name "eth[0123...]".
    */
@@ -438,11 +435,23 @@ static __init int trif_probe(void)
 }
 #endif
 
+       
+/*
+ *     The loopback device is global so it can be directly referenced
+ *     by the network code. Also, it must be first on device list.
+ */
+extern int loopback_init(void);
+
 /*  Statically configured drivers -- order matters here. */
 void __init probe_old_netdevs(void)
 {
        int num;
 
+       if (loopback_init()) {
+               printk(KERN_ERR "Network loopback device setup failed\n");
+       }
+
+       
 #ifdef CONFIG_SBNI
        for (num = 0; num < 8; ++num)
                if (sbni_probe())
@@ -477,18 +486,6 @@ static struct net_device dev_ltpc = {
 #undef NEXT_DEV
 #define NEXT_DEV       (&dev_ltpc)
 #endif  /* LTPC */
-       
-/*
- *     The loopback device is global so it can be directly referenced
- *     by the network code. Also, it must be first on device list.
- */
-
-extern int loopback_init(struct net_device *dev);
-struct net_device loopback_dev = {
-       .name           = "lo",
-       .next           = NEXT_DEV,
-       .init           = loopback_init
-};
 
 /*
  * The @dev_base list is protected by @dev_base_lock and the rtln
@@ -509,6 +506,6 @@ struct net_device loopback_dev = {
  * unregister_netdevice(), which must be called with the rtnl
  * semaphore held.
  */
-struct net_device *dev_base = &loopback_dev;
+struct net_device *dev_base;
 rwlock_t dev_base_lock = RW_LOCK_UNLOCKED;
 
index 7382804af6b06b8abd0087b97b9cbfec0c370a68..5dd2b3393edccf216562e77d10cfff2abac3eed5 100644 (file)
@@ -55,6 +55,7 @@
 #include <linux/ip.h>
 #include <linux/tcp.h>
 
+
 #define LOOPBACK_OVERHEAD (128 + MAX_HEADER + 16 + 16)
 
 /* KISS: just allocate small chunks and copy bits.
@@ -152,10 +153,12 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
        }
 
        dev->last_rx = jiffies;
-       stats->rx_bytes+=skb->len;
-       stats->tx_bytes+=skb->len;
-       stats->rx_packets++;
-       stats->tx_packets++;
+       if (likely(stats)) {
+               stats->rx_bytes+=skb->len;
+               stats->tx_bytes+=skb->len;
+               stats->rx_packets++;
+               stats->tx_packets++;
+       }
 
        netif_rx(skb);
 
@@ -167,36 +170,35 @@ static struct net_device_stats *get_stats(struct net_device *dev)
        return (struct net_device_stats *)dev->priv;
 }
 
-/* Initialize the rest of the LOOPBACK device. */
-int __init loopback_init(struct net_device *dev)
-{
-       dev->mtu                = (16 * 1024) + 20 + 20 + 12;
-       dev->hard_start_xmit    = loopback_xmit;
-       dev->hard_header        = eth_header;
-       dev->hard_header_cache  = eth_header_cache;
-       dev->header_cache_update= eth_header_cache_update;
-       dev->hard_header_len    = ETH_HLEN;             /* 14                   */
-       dev->addr_len           = ETH_ALEN;             /* 6                    */
-       dev->tx_queue_len       = 0;
-       dev->type               = ARPHRD_LOOPBACK;      /* 0x0001               */
-       dev->rebuild_header     = eth_rebuild_header;
-       dev->flags              = IFF_LOOPBACK;
-       dev->features           = NETIF_F_SG|NETIF_F_FRAGLIST|NETIF_F_NO_CSUM|NETIF_F_HIGHDMA;
-
-       /* Current netfilter will die with oom linearizing large skbs,
-        * however this will be cured before 2.5.x is done.
-        */
-       dev->features          |= NETIF_F_TSO;
-
-       dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL);
-       if (dev->priv == NULL)
-                       return -ENOMEM;
-       memset(dev->priv, 0, sizeof(struct net_device_stats));
-       dev->get_stats = get_stats;
+struct net_device loopback_dev = {
+       .name                   = "lo",
+       .mtu                    = (16 * 1024) + 20 + 20 + 12,
+       .hard_start_xmit        = loopback_xmit,
+       .hard_header            = eth_header,
+       .hard_header_cache      = eth_header_cache,
+       .header_cache_update    = eth_header_cache_update,
+       .hard_header_len        = ETH_HLEN,     /* 14   */
+       .addr_len               = ETH_ALEN,     /* 6    */
+       .tx_queue_len           = 0,
+       .type                   = ARPHRD_LOOPBACK,      /* 0x0001*/
+       .rebuild_header         = eth_rebuild_header,
+       .flags                  = IFF_LOOPBACK,
+       .features               = NETIF_F_SG|NETIF_F_FRAGLIST
+                                 |NETIF_F_NO_CSUM|NETIF_F_HIGHDMA|NETIF_F_TSO,
+};
 
-       /*
-        *      Fill in the generic fields of the device structure. 
-        */
-   
-       return(0);
+/* Setup and register the of the LOOPBACK device. */
+int __init loopback_init(void)
+{
+       struct net_device_stats *stats;
+
+       /* Can survive without statistics */
+       stats = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL);
+       if (stats) {
+               memset(stats, 0, sizeof(struct net_device_stats));
+               loopback_dev.priv = stats;
+               loopback_dev.get_stats = &get_stats;
+       }
+       
+       return register_netdev(&loopback_dev);
 };
index 1ac07dc5077e2d22235ac4184a6995f17d3691f3..8a598f7f300cc8b7ee7c63f243f97d6c7eb1ce96 100644 (file)
@@ -2981,7 +2981,6 @@ int unregister_netdevice(struct net_device *dev)
  */
 static int __init net_dev_init(void)
 {
-       struct net_device *dev, **dp;
        int i, rc = -ENOMEM;
 
        BUG_ON(!dev_boot_phase);
@@ -3027,75 +3026,6 @@ static int __init net_dev_init(void)
        add_timer(&samp_timer);
 #endif
 
-       /*
-        *      Add the devices.
-        *      If the call to dev->init fails, the dev is removed
-        *      from the chain disconnecting the device until the
-        *      next reboot.
-        *
-        *      NB At boot phase networking is dead. No locking is required.
-        *      But we still preserve dev_base_lock for sanity.
-        */
-
-       dp = &dev_base;
-       while ((dev = *dp) != NULL) {
-               spin_lock_init(&dev->queue_lock);
-               spin_lock_init(&dev->xmit_lock);
-#ifdef CONFIG_NET_FASTROUTE
-               dev->fastpath_lock = RW_LOCK_UNLOCKED;
-#endif
-               dev->xmit_lock_owner = -1;
-               dev->iflink = -1;
-               dev_hold(dev);
-
-               /*
-                * Allocate name. If the init() fails
-                * the name will be reissued correctly.
-                */
-               if (strchr(dev->name, '%'))
-                       dev_alloc_name(dev, dev->name);
-
-               /*
-                * Check boot time settings for the device.
-                */
-               netdev_boot_setup_check(dev);
-
-               if ( (dev->init && dev->init(dev)) ||
-                    netdev_register_sysfs(dev) ) {
-                       /*
-                        * It failed to come up. It will be unhooked later.
-                        * dev_alloc_name can now advance to next suitable
-                        * name that is checked next.
-                        */
-                       dp = &dev->next;
-               } else {
-                       dp = &dev->next;
-                       dev->ifindex = dev_new_index();
-                       dev->reg_state = NETREG_REGISTERED;
-                       if (dev->iflink == -1)
-                               dev->iflink = dev->ifindex;
-                       if (!dev->rebuild_header)
-                               dev->rebuild_header = default_rebuild_header;
-                       dev_init_scheduler(dev);
-                       set_bit(__LINK_STATE_PRESENT, &dev->state);
-               }
-       }
-
-       /*
-        * Unhook devices that failed to come up
-        */
-       dp = &dev_base;
-       while ((dev = *dp) != NULL) {
-               if (dev->reg_state != NETREG_REGISTERED) {
-                       write_lock_bh(&dev_base_lock);
-                       *dp = dev->next;
-                       write_unlock_bh(&dev_base_lock);
-                       dev_put(dev);
-               } else {
-                       dp = &dev->next;
-               }
-       }
-
        dev_boot_phase = 0;
 
        probe_old_netdevs();