Commit fe47f125 authored by Dmitry Tarnyagin's avatar Dmitry Tarnyagin Committed by David S. Miller

caif-hsi: Fixing a race condition in the caif_hsi code

cfhsi->tx_state was not protected by a spin lock. TX soft-irq could interrupt
cfhsi_tx_done_work work leading to inconsistent state of the driver.
Signed-off-by: default avatarSjur Brændeland <sjur.brandeland@stericsson.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 94230feb
...@@ -304,14 +304,22 @@ static void cfhsi_tx_done_work(struct work_struct *work) ...@@ -304,14 +304,22 @@ static void cfhsi_tx_done_work(struct work_struct *work)
spin_unlock_bh(&cfhsi->lock); spin_unlock_bh(&cfhsi->lock);
/* Create HSI frame. */ /* Create HSI frame. */
do {
len = cfhsi_tx_frm(desc, cfhsi); len = cfhsi_tx_frm(desc, cfhsi);
if (!len) { if (!len) {
spin_lock_bh(&cfhsi->lock);
if (unlikely(skb_peek(&cfhsi->qhead))) {
spin_unlock_bh(&cfhsi->lock);
continue;
}
cfhsi->tx_state = CFHSI_TX_STATE_IDLE; cfhsi->tx_state = CFHSI_TX_STATE_IDLE;
/* Start inactivity timer. */ /* Start inactivity timer. */
mod_timer(&cfhsi->timer, mod_timer(&cfhsi->timer,
jiffies + CFHSI_INACTIVITY_TOUT); jiffies + CFHSI_INACTIVITY_TOUT);
break; spin_unlock_bh(&cfhsi->lock);
goto done;
} }
} while (!len);
/* Set up new transfer. */ /* Set up new transfer. */
res = cfhsi->dev->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->dev); res = cfhsi->dev->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->dev);
...@@ -320,6 +328,9 @@ static void cfhsi_tx_done_work(struct work_struct *work) ...@@ -320,6 +328,9 @@ static void cfhsi_tx_done_work(struct work_struct *work)
__func__, res); __func__, res);
} }
} while (res < 0); } while (res < 0);
done:
return;
} }
static void cfhsi_tx_done_cb(struct cfhsi_drv *drv) static void cfhsi_tx_done_cb(struct cfhsi_drv *drv)
......
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