Skip to content

Commit

Permalink
caif-hsi: Fixing a race condition in the caif_hsi code
Browse files Browse the repository at this point in the history
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: Sjur Brændeland <sjur.brandeland@stericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Dmitry Tarnyagin authored and David S. Miller committed Oct 19, 2011
1 parent 94230fe commit fe47f12
Showing 1 changed file with 18 additions and 7 deletions.
25 changes: 18 additions & 7 deletions drivers/net/caif/caif_hsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -304,14 +304,22 @@ static void cfhsi_tx_done_work(struct work_struct *work)
spin_unlock_bh(&cfhsi->lock);

/* Create HSI frame. */
len = cfhsi_tx_frm(desc, cfhsi);
if (!len) {
cfhsi->tx_state = CFHSI_TX_STATE_IDLE;
/* Start inactivity timer. */
mod_timer(&cfhsi->timer,
do {
len = cfhsi_tx_frm(desc, cfhsi);
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;
/* Start inactivity timer. */
mod_timer(&cfhsi->timer,
jiffies + CFHSI_INACTIVITY_TOUT);
break;
}
spin_unlock_bh(&cfhsi->lock);
goto done;
}
} while (!len);

/* Set up new transfer. */
res = cfhsi->dev->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->dev);
Expand All @@ -320,6 +328,9 @@ static void cfhsi_tx_done_work(struct work_struct *work)
__func__, res);
}
} while (res < 0);

done:
return;
}

static void cfhsi_tx_done_cb(struct cfhsi_drv *drv)
Expand Down

0 comments on commit fe47f12

Please sign in to comment.