Linux IEEE 802.15.4 and 6LoWPAN development
 help / color / mirror / Atom feed
* Kernel crash when using multiple interfaces
@ 2015-05-15 12:54 Simon Vincent
  2015-05-15 14:20 ` Alexander Aring
  2015-05-15 15:28 ` Alexander Aring
  0 siblings, 2 replies; 12+ messages in thread
From: Simon Vincent @ 2015-05-15 12:54 UTC (permalink / raw)
  To: linux-wpan

I have found the Kernel crashes when multiple 802.15.4 interfaces are 
used at the same time.
I have tracked it down in the kernel to net/mac802154/tx.c
The problem is the ieee802154_xmit_cb is a global variable so after it 
has been assigned and added to the work queue it can be 
corrupted/changed by another interface transmitting a packet.

I have fixed it by allocating the structure on the heap. If this is a 
satisfactory fix I can submit it as a patch.

  diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c
index c62e956..168d377 100644
--- a/net/mac802154/tx.c
+++ b/net/mac802154/tx.c
@@ -39,8 +39,6 @@ struct ieee802154_xmit_cb {
      struct ieee802154_local *local;
  };

-static struct ieee802154_xmit_cb ieee802154_xmit_cb;
-
  static void ieee802154_xmit_worker(struct work_struct *work)
  {
      struct ieee802154_xmit_cb *cb =
@@ -66,6 +64,7 @@ static void ieee802154_xmit_worker(struct work_struct 
*work)
      dev->stats.tx_bytes += skb->len;

      rtnl_unlock();
+    kfree(cb);

      return;

@@ -74,6 +73,7 @@ err_tx:
      ieee802154_wake_queue(&local->hw);
      rtnl_unlock();
      kfree_skb(skb);
+    kfree(cb);
      netdev_dbg(dev, "transmission failed\n");
  }

@@ -81,8 +81,8 @@ static netdev_tx_t
  ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb)
  {
      struct net_device *dev = skb->dev;
+    struct ieee802154_xmit_cb *ieee802154_xmit_cb_ptr;
      int ret;
-
      if (!(local->hw.flags & IEEE802154_HW_TX_OMIT_CKSUM)) {
          u16 crc = crc_ccitt(0, skb->data, skb->len);

@@ -106,11 +106,11 @@ ieee802154_tx(struct ieee802154_local *local, 
struct sk_buff *skb)
          dev->stats.tx_packets++;
          dev->stats.tx_bytes += skb->len;
      } else {
-        INIT_WORK(&ieee802154_xmit_cb.work, ieee802154_xmit_worker);
-        ieee802154_xmit_cb.skb = skb;
-        ieee802154_xmit_cb.local = local;
-
-        queue_work(local->workqueue, &ieee802154_xmit_cb.work);
+        ieee802154_xmit_cb_ptr = kmalloc(sizeof(struct 
ieee802154_xmit_cb), GFP_ATOMIC);
+        INIT_WORK(&ieee802154_xmit_cb_ptr->work, ieee802154_xmit_worker);
+        ieee802154_xmit_cb_ptr->skb = skb;
+        ieee802154_xmit_cb_ptr->local = local;
+        queue_work(local->workqueue, &ieee802154_xmit_cb_ptr->work);
      }

      return NETDEV_TX_OK;


- Simon

^ permalink raw reply related	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2015-05-19 11:18 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-15 12:54 Kernel crash when using multiple interfaces Simon Vincent
2015-05-15 14:20 ` Alexander Aring
2015-05-15 15:02   ` Simon Vincent
2015-05-15 15:23     ` Alexander Aring
2015-05-16 15:33     ` Alexander Aring
2015-05-18 10:57       ` Simon Vincent
2015-05-18 14:00         ` Alexander Aring
2015-05-18 15:05           ` Simon Vincent
2015-05-18 15:37             ` Alexander Aring
2015-05-18 16:27               ` Alexander Aring
2015-05-19 11:18                 ` Simon Vincent
2015-05-15 15:28 ` Alexander Aring

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox