Skip to content

Commit a7ecbe9

Browse files
ndosschetiwai
authored andcommitted
firewire: core: extend card->lock in fw_core_handle_bus_reset
card->local_node and card->bm_retries are both always accessed under card->lock. fw_core_handle_bus_reset has a check whose condition depends on card->local_node and whose body writes to card->bm_retries. Both of these accesses are not under card->lock. Move the lock acquiring of card->lock to before this check such that these accesses do happen when card->lock is held. fw_destroy_nodes is called inside the check. Since fw_destroy_nodes already acquires card->lock inside its function body, move this out to the callsites of fw_destroy_nodes. Also add a comment to indicate which locking is necessary when calling fw_destroy_nodes. Cc: <stable@vger.kernel.org> Signed-off-by: Niels Dossche <dossche.niels@gmail.com> Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Link: https://lore.kernel.org/r/20220409041243.603210-4-o-takashi@sakamocchi.jp Signed-off-by: Takashi Iwai <tiwai@suse.de>
1 parent 9423973 commit a7ecbe9

2 files changed

Lines changed: 6 additions & 6 deletions

File tree

drivers/firewire/core-card.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,7 @@ EXPORT_SYMBOL_GPL(fw_card_release);
668668
void fw_core_remove_card(struct fw_card *card)
669669
{
670670
struct fw_card_driver dummy_driver = dummy_driver_template;
671+
unsigned long flags;
671672

672673
card->driver->update_phy_reg(card, 4,
673674
PHY_LINK_ACTIVE | PHY_CONTENDER, 0);
@@ -682,7 +683,9 @@ void fw_core_remove_card(struct fw_card *card)
682683
dummy_driver.stop_iso = card->driver->stop_iso;
683684
card->driver = &dummy_driver;
684685

686+
spin_lock_irqsave(&card->lock, flags);
685687
fw_destroy_nodes(card);
688+
spin_unlock_irqrestore(&card->lock, flags);
686689

687690
/* Wait for all users, especially device workqueue jobs, to finish. */
688691
fw_card_put(card);

drivers/firewire/core-topology.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -375,16 +375,13 @@ static void report_found_node(struct fw_card *card,
375375
card->bm_retries = 0;
376376
}
377377

378+
/* Must be called with card->lock held */
378379
void fw_destroy_nodes(struct fw_card *card)
379380
{
380-
unsigned long flags;
381-
382-
spin_lock_irqsave(&card->lock, flags);
383381
card->color++;
384382
if (card->local_node != NULL)
385383
for_each_fw_node(card, card->local_node, report_lost_node);
386384
card->local_node = NULL;
387-
spin_unlock_irqrestore(&card->lock, flags);
388385
}
389386

390387
static void move_tree(struct fw_node *node0, struct fw_node *node1, int port)
@@ -510,6 +507,8 @@ void fw_core_handle_bus_reset(struct fw_card *card, int node_id, int generation,
510507
struct fw_node *local_node;
511508
unsigned long flags;
512509

510+
spin_lock_irqsave(&card->lock, flags);
511+
513512
/*
514513
* If the selfID buffer is not the immediate successor of the
515514
* previously processed one, we cannot reliably compare the
@@ -521,8 +520,6 @@ void fw_core_handle_bus_reset(struct fw_card *card, int node_id, int generation,
521520
card->bm_retries = 0;
522521
}
523522

524-
spin_lock_irqsave(&card->lock, flags);
525-
526523
card->broadcast_channel_allocated = card->broadcast_channel_auto_allocated;
527524
card->node_id = node_id;
528525
/*

0 commit comments

Comments
 (0)