]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - net/netrom/af_netrom.c
[IPV4] devinet: inetdev_init out label moved after RCU assignment
[mv-sheeva.git] / net / netrom / af_netrom.c
index 389a4119e1b405a9cebbf11f4a9076ff4b2d95c4..43bbe2c9e49aa48f8b8995e857945f440dc98acd 100644 (file)
@@ -65,6 +65,14 @@ static DEFINE_SPINLOCK(nr_list_lock);
 
 static const struct proto_ops nr_proto_ops;
 
+/*
+ * NETROM network devices are virtual network devices encapsulating NETROM
+ * frames into AX.25 which will be sent through an AX.25 device, so form a
+ * special "super class" of normal net devices; split their locks off into a
+ * separate class since they always nest.
+ */
+static struct lock_class_key nr_netdev_xmit_lock_key;
+
 /*
  *     Socket removal during an interrupt is now safe.
  */
@@ -986,18 +994,18 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device *dev)
        nr_make->vl        = 0;
        nr_make->state     = NR_STATE_3;
        sk_acceptq_added(sk);
-
-       nr_insert_socket(make);
-
        skb_queue_head(&sk->sk_receive_queue, skb);
 
-       nr_start_heartbeat(make);
-       nr_start_idletimer(make);
-
        if (!sock_flag(sk, SOCK_DEAD))
                sk->sk_data_ready(sk, skb->len);
 
        bh_unlock_sock(sk);
+
+       nr_insert_socket(make);
+
+       nr_start_heartbeat(make);
+       nr_start_idletimer(make);
+
        return 1;
 }
 
@@ -1369,6 +1377,15 @@ static struct notifier_block nr_dev_notifier = {
 
 static struct net_device **dev_nr;
 
+static struct ax25_protocol nr_pid = {
+       .pid    = AX25_P_NETROM,
+       .func   = nr_route_frame
+};
+
+static struct ax25_linkfail nr_linkfail_notifier = {
+       .func   = nr_link_failed,
+};
+
 static int __init nr_proto_init(void)
 {
        int i;
@@ -1382,14 +1399,12 @@ static int __init nr_proto_init(void)
                return -1;
        }
 
-       dev_nr = kmalloc(nr_ndevs * sizeof(struct net_device *), GFP_KERNEL);
+       dev_nr = kzalloc(nr_ndevs * sizeof(struct net_device *), GFP_KERNEL);
        if (dev_nr == NULL) {
                printk(KERN_ERR "NET/ROM: nr_proto_init - unable to allocate device array\n");
                return -1;
        }
 
-       memset(dev_nr, 0x00, nr_ndevs * sizeof(struct net_device *));
-
        for (i = 0; i < nr_ndevs; i++) {
                char name[IFNAMSIZ];
                struct net_device *dev;
@@ -1407,6 +1422,7 @@ static int __init nr_proto_init(void)
                        free_netdev(dev);
                        goto fail;
                }
+               lockdep_set_class(&dev->_xmit_lock, &nr_netdev_xmit_lock_key);
                dev_nr[i] = dev;
        }
 
@@ -1417,8 +1433,8 @@ static int __init nr_proto_init(void)
                
        register_netdevice_notifier(&nr_dev_notifier);
 
-       ax25_protocol_register(AX25_P_NETROM, nr_route_frame);
-       ax25_linkfail_register(nr_link_failed);
+       ax25_register_pid(&nr_pid);
+       ax25_linkfail_register(&nr_linkfail_notifier);
 
 #ifdef CONFIG_SYSCTL
        nr_register_sysctl();
@@ -1467,7 +1483,7 @@ static void __exit nr_exit(void)
        nr_unregister_sysctl();
 #endif
 
-       ax25_linkfail_release(nr_link_failed);
+       ax25_linkfail_release(&nr_linkfail_notifier);
        ax25_protocol_release(AX25_P_NETROM);
 
        unregister_netdevice_notifier(&nr_dev_notifier);