Search Linux Wireless

[PATCH] rtl8187: Fix crash on unload when using SLUB debug

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Herton Ronaldo Krzesinski <herton@xxxxxxxxxxxxxxx>
Reported-by: Hin-Tak Leung <htl10@xxxxxxxxxxxxxxxxxxxxx>

After the code was modified to use urb anchors ("rtl8187: Use usb anchor
facilities to manage urbs"), rtl8187 began generating an intermittent GPF
on shutdown when using SLUB with debugging enabled. Furthermore, rebooting
the system with a ping running caused a GPF every time. There are two problems:
(1) incorrect locking in the rtl8187_rx_cb() routine, a pre-existing bug that
apparently had not been triggered before, and (2) duplicate freeing of receive
skbs that was probably introduced with the change to anchors.

Signed-off-by: Herton Ronaldo Krzesinski <herton@xxxxxxxxxxxxxxx>
Signed-off-by: Larry Finger <Larry.Finger@xxxxxxxxxxxx>
Tested-by: Hin-Tak Leung <htl10@xxxxxxxxxxxxxxxxxxxxx>
---

John,

As the patch that exposed the first bug will be in 2.6.29, this one needs to be
in 2.6.29 as well.

Larry
---

Index: wireless-testing/drivers/net/wireless/rtl818x/rtl8187_dev.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ wireless-testing/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -294,15 +294,16 @@ static void rtl8187_rx_cb(struct urb *ur
 	int rate, signal;
 	u32 flags;
 	u32 quality;
+	unsigned long f;
 
-	spin_lock(&priv->rx_queue.lock);
+	spin_lock_irqsave(&priv->rx_queue.lock, f);
 	if (skb->next)
 		__skb_unlink(skb, &priv->rx_queue);
 	else {
-		spin_unlock(&priv->rx_queue.lock);
+		spin_unlock_irqrestore(&priv->rx_queue.lock, f);
 		return;
 	}
-	spin_unlock(&priv->rx_queue.lock);
+	spin_unlock_irqrestore(&priv->rx_queue.lock, f);
 	skb_put(skb, urb->actual_length);
 
 	if (unlikely(urb->status)) {
@@ -942,7 +943,6 @@ static int rtl8187_start(struct ieee8021
 static void rtl8187_stop(struct ieee80211_hw *dev)
 {
 	struct rtl8187_priv *priv = dev->priv;
-	struct rtl8187_rx_info *info;
 	struct sk_buff *skb;
 	u32 reg;
 
@@ -961,10 +961,6 @@ static void rtl8187_stop(struct ieee8021
 	rtl818x_iowrite8(priv, &priv->map->CONFIG4, reg | RTL818X_CONFIG4_VCOOFF);
 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
 
-	while ((skb = skb_dequeue(&priv->rx_queue))) {
-		info = (struct rtl8187_rx_info *)skb->cb;
-		kfree_skb(skb);
-	}
 	while ((skb = skb_dequeue(&priv->b_tx_status.queue)))
 		dev_kfree_skb_any(skb);
 
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux