wl3501_cs: Add spinlock to wl3501_reset
Likely wl3501_reset should acquire spinlock as wl3501_{open, close}. One of calls of wl3501_reset has been already protected. The others were unprotected and might lead to a race condition. The patch adds spinlock into the wl3501_reset and removes it from wl3501_tx_timeout. Found by Linux Driver Verification project (linuxtesting.org) Signed-off-by: Pavel Andrianov <andrianov@ispras.ru> Acked-by: Vaishali Thakkar <vaishali.thakkar@oracle.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
Родитель
b0d80f19c1
Коммит
bd6b024265
|
@ -1258,7 +1258,9 @@ static int wl3501_reset(struct net_device *dev)
|
|||
{
|
||||
struct wl3501_card *this = netdev_priv(dev);
|
||||
int rc = -ENODEV;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&this->lock, flags);
|
||||
wl3501_block_interrupt(this);
|
||||
|
||||
if (wl3501_init_firmware(this)) {
|
||||
|
@ -1280,20 +1282,17 @@ static int wl3501_reset(struct net_device *dev)
|
|||
pr_debug("%s: device reset", dev->name);
|
||||
rc = 0;
|
||||
out:
|
||||
spin_unlock_irqrestore(&this->lock, flags);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void wl3501_tx_timeout(struct net_device *dev)
|
||||
{
|
||||
struct wl3501_card *this = netdev_priv(dev);
|
||||
struct net_device_stats *stats = &dev->stats;
|
||||
unsigned long flags;
|
||||
int rc;
|
||||
|
||||
stats->tx_errors++;
|
||||
spin_lock_irqsave(&this->lock, flags);
|
||||
rc = wl3501_reset(dev);
|
||||
spin_unlock_irqrestore(&this->lock, flags);
|
||||
if (rc)
|
||||
printk(KERN_ERR "%s: Error %d resetting card on Tx timeout!\n",
|
||||
dev->name, rc);
|
||||
|
|
Загрузка…
Ссылка в новой задаче