Skip to content

Commit

Permalink
firewire: core: extend card->lock in fw_core_handle_bus_reset
Browse files Browse the repository at this point in the history
commit a7ecbe92b9243edbe94772f6f2c854e4142a3345 upstream.

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: <[email protected]>
Signed-off-by: Niels Dossche <[email protected]>
Signed-off-by: Takashi Sakamoto <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
nielsdos authored and gregkh committed May 12, 2022
1 parent 344c9c8 commit 71fb770
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 6 deletions.
3 changes: 3 additions & 0 deletions drivers/firewire/core-card.c
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,7 @@ EXPORT_SYMBOL_GPL(fw_card_release);
void fw_core_remove_card(struct fw_card *card)
{
struct fw_card_driver dummy_driver = dummy_driver_template;
unsigned long flags;

card->driver->update_phy_reg(card, 4,
PHY_LINK_ACTIVE | PHY_CONTENDER, 0);
Expand All @@ -695,7 +696,9 @@ void fw_core_remove_card(struct fw_card *card)
dummy_driver.stop_iso = card->driver->stop_iso;
card->driver = &dummy_driver;

spin_lock_irqsave(&card->lock, flags);
fw_destroy_nodes(card);
spin_unlock_irqrestore(&card->lock, flags);

/* Wait for all users, especially device workqueue jobs, to finish. */
fw_card_put(card);
Expand Down
9 changes: 3 additions & 6 deletions drivers/firewire/core-topology.c
Original file line number Diff line number Diff line change
Expand Up @@ -387,16 +387,13 @@ static void report_found_node(struct fw_card *card,
card->bm_retries = 0;
}

/* Must be called with card->lock held */
void fw_destroy_nodes(struct fw_card *card)
{
unsigned long flags;

spin_lock_irqsave(&card->lock, flags);
card->color++;
if (card->local_node != NULL)
for_each_fw_node(card, card->local_node, report_lost_node);
card->local_node = NULL;
spin_unlock_irqrestore(&card->lock, flags);
}

static void move_tree(struct fw_node *node0, struct fw_node *node1, int port)
Expand Down Expand Up @@ -522,6 +519,8 @@ void fw_core_handle_bus_reset(struct fw_card *card, int node_id, int generation,
struct fw_node *local_node;
unsigned long flags;

spin_lock_irqsave(&card->lock, flags);

/*
* If the selfID buffer is not the immediate successor of the
* previously processed one, we cannot reliably compare the
Expand All @@ -533,8 +532,6 @@ void fw_core_handle_bus_reset(struct fw_card *card, int node_id, int generation,
card->bm_retries = 0;
}

spin_lock_irqsave(&card->lock, flags);

card->broadcast_channel_allocated = card->broadcast_channel_auto_allocated;
card->node_id = node_id;
/*
Expand Down

0 comments on commit 71fb770

Please sign in to comment.