aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2014-03-03 17:22:35 -0500
committerStefan Richter <stefanr@s5r6.in-berlin.de>2014-12-10 14:53:20 -0500
commit0765cbd3be699b4a72db67069247d514f06a1e4f (patch)
treedd57c6f137bdfdb39d35d1b89241aa227726a213
parent0238507b951857360461b0635111e7376ffd44d1 (diff)
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>
-rw-r--r--drivers/firewire/sbp2.c14
1 files changed, 6 insertions, 8 deletions
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c
index 7aef911fdc71..c7fc78c23978 100644
--- a/drivers/firewire/sbp2.c
+++ b/drivers/firewire/sbp2.c
@@ -689,14 +689,12 @@ static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu)
689 689
690static inline void sbp2_allow_block(struct sbp2_logical_unit *lu) 690static inline void sbp2_allow_block(struct sbp2_logical_unit *lu)
691{ 691{
692 /* 692 struct sbp2_target *tgt = lu->tgt;
693 * We may access dont_block without taking card->lock here: 693 struct fw_card *card = target_parent_device(tgt)->card;
694 * All callers of sbp2_allow_block() and all callers of sbp2_unblock() 694
695 * are currently serialized against each other. 695 spin_lock_irq(&card->lock);
696 * And a wrong result in sbp2_conditionally_block()'s access of 696 --tgt->dont_block;
697 * dont_block is rather harmless, it simply misses its first chance. 697 spin_unlock_irq(&card->lock);
698 */
699 --lu->tgt->dont_block;
700} 698}
701 699
702/* 700/*