Commit d8588227 authored by Herton Ronaldo Krzesinski's avatar Herton Ronaldo Krzesinski Committed by John W. Linville

rtl8187: Fix crash on unload when using SLUB debug

Reported-by: default avatarHin-Tak Leung <htl10@users.sourceforge.net>

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: default avatarHerton Ronaldo Krzesinski <herton@mandriva.com.br>
Signed-off-by: default avatarLarry Finger <Larry.Finger@lwfinger.net>
Tested-by: default avatarHin-Tak Leung <htl10@users.sourceforge.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 0a5ec96a
...@@ -294,15 +294,16 @@ static void rtl8187_rx_cb(struct urb *urb) ...@@ -294,15 +294,16 @@ static void rtl8187_rx_cb(struct urb *urb)
int rate, signal; int rate, signal;
u32 flags; u32 flags;
u32 quality; u32 quality;
unsigned long f;
spin_lock(&priv->rx_queue.lock); spin_lock_irqsave(&priv->rx_queue.lock, f);
if (skb->next) if (skb->next)
__skb_unlink(skb, &priv->rx_queue); __skb_unlink(skb, &priv->rx_queue);
else { else {
spin_unlock(&priv->rx_queue.lock); spin_unlock_irqrestore(&priv->rx_queue.lock, f);
return; return;
} }
spin_unlock(&priv->rx_queue.lock); spin_unlock_irqrestore(&priv->rx_queue.lock, f);
skb_put(skb, urb->actual_length); skb_put(skb, urb->actual_length);
if (unlikely(urb->status)) { if (unlikely(urb->status)) {
...@@ -942,7 +943,6 @@ static int rtl8187_start(struct ieee80211_hw *dev) ...@@ -942,7 +943,6 @@ static int rtl8187_start(struct ieee80211_hw *dev)
static void rtl8187_stop(struct ieee80211_hw *dev) static void rtl8187_stop(struct ieee80211_hw *dev)
{ {
struct rtl8187_priv *priv = dev->priv; struct rtl8187_priv *priv = dev->priv;
struct rtl8187_rx_info *info;
struct sk_buff *skb; struct sk_buff *skb;
u32 reg; u32 reg;
...@@ -961,10 +961,6 @@ static void rtl8187_stop(struct ieee80211_hw *dev) ...@@ -961,10 +961,6 @@ static void rtl8187_stop(struct ieee80211_hw *dev)
rtl818x_iowrite8(priv, &priv->map->CONFIG4, reg | RTL818X_CONFIG4_VCOOFF); rtl818x_iowrite8(priv, &priv->map->CONFIG4, reg | RTL818X_CONFIG4_VCOOFF);
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 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))) while ((skb = skb_dequeue(&priv->b_tx_status.queue)))
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment