ir247_irlan_dynalloc-2.diff :
---------------------------
        o [CRITICA] Don't pass the same skb to two different state machines
        <Following patch from Martin Diehl, modified by me>
        o [CRITICA] Don't flag netdev as NETIF_F_DYNALLOC, because not kmalloc

diff -u -p -r linux/net/irda/irlan-d8/irlan_common.c 
linux/net/irda/irlan/irlan_common.c
--- linux/net/irda/irlan-d8/irlan_common.c      Sun Sep 30 12:26:09 2001
+++ linux/net/irda/irlan/irlan_common.c Wed Jan  9 11:08:41 2002
@@ -317,8 +317,15 @@ void irlan_connect_indication(void *inst
 
        del_timer(&self->watchdog_timer);
 
-       irlan_do_provider_event(self, IRLAN_DATA_CONNECT_INDICATION, skb);
-       irlan_do_client_event(self, IRLAN_DATA_CONNECT_INDICATION, skb);
+       /* If you want to pass the skb to *both* state machines, you will
+        * need to skb_clone() it, so that you don't free it twice.
+        * As the state machines don't need it, git rid of it here...
+        * Jean II */
+       if (skb)
+               dev_kfree_skb(skb);
+
+       irlan_do_provider_event(self, IRLAN_DATA_CONNECT_INDICATION, NULL);
+       irlan_do_client_event(self, IRLAN_DATA_CONNECT_INDICATION, NULL);
 
        if (self->provider.access_type == ACCESS_PEER) {
                /* 
@@ -421,6 +428,13 @@ void irlan_disconnect_indication(void *i
                break;
        }
        
+       /* If you want to pass the skb to *both* state machines, you will
+        * need to skb_clone() it, so that you don't free it twice.
+        * As the state machines don't need it, git rid of it here...
+        * Jean II */
+       if (userdata)
+               dev_kfree_skb(userdata);
+
        irlan_do_client_event(self, IRLAN_LMP_DISCONNECT, NULL);
        irlan_do_provider_event(self, IRLAN_LMP_DISCONNECT, NULL);
        
diff -u -p -r linux/net/irda/irlan-d8/irlan_eth.c linux/net/irda/irlan/irlan_eth.c
--- linux/net/irda/irlan-d8/irlan_eth.c Wed Jan  9 11:00:53 2002
+++ linux/net/irda/irlan/irlan_eth.c    Tue Jan  8 18:33:45 2002
@@ -61,7 +61,16 @@ int irlan_eth_init(struct net_device *de
        dev->hard_start_xmit    = irlan_eth_xmit; 
        dev->get_stats          = irlan_eth_get_stats;
        dev->set_multicast_list = irlan_eth_set_multicast_list;
-       dev->features          |= NETIF_F_DYNALLOC;
+
+       /* NETIF_F_DYNALLOC feature was set by irlan_eth_init() and would
+        * cause the unregister_netdev() to do asynch completion _and_
+        * kfree self->dev afterwards. Which is really bad because the
+        * netdevice was not allocated separately but is embedded in
+        * our control block and therefore gets freed with *self.
+        * The only reason why this would have been enabled is to hide
+        * some netdev refcount issues. If unregister_netdev() blocks
+        * forever, tell us about it... */
+       //dev->features          |= NETIF_F_DYNALLOC;
 
        ether_setup(dev);
        
_______________________________________________
Linux-IrDA mailing list  -  [EMAIL PROTECTED]
http://www.pasta.cs.UiT.No/mailman/listinfo/linux-irda

Reply via email to