firewire: sbp2: protect a reference counter properly
The assertion in the comment in sbp2_allow_block() is no longer true. Or maybe it never was true. At least now, the sole caller of sbp2_allow_block(), sbp2_login, can run concurrently to one of sbp2_unblock()'s callers, sbp2_remove. sbp2_login is performed by sbp2_logical_unit.work. sbp2_remove is performed by fw_device.work. sbp2_remove cancels sbp2_logical_unit.work, but only after it called sbp2_unblock. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
This commit is contained in:
Родитель
0238507b95
Коммит
0765cbd3be
|
@ -689,14 +689,12 @@ static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu)
|
||||||
|
|
||||||
static inline void sbp2_allow_block(struct sbp2_logical_unit *lu)
|
static inline void sbp2_allow_block(struct sbp2_logical_unit *lu)
|
||||||
{
|
{
|
||||||
/*
|
struct sbp2_target *tgt = lu->tgt;
|
||||||
* We may access dont_block without taking card->lock here:
|
struct fw_card *card = target_parent_device(tgt)->card;
|
||||||
* All callers of sbp2_allow_block() and all callers of sbp2_unblock()
|
|
||||||
* are currently serialized against each other.
|
spin_lock_irq(&card->lock);
|
||||||
* And a wrong result in sbp2_conditionally_block()'s access of
|
--tgt->dont_block;
|
||||||
* dont_block is rather harmless, it simply misses its first chance.
|
spin_unlock_irq(&card->lock);
|
||||||
*/
|
|
||||||
--lu->tgt->dont_block;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Загрузка…
Ссылка в новой задаче