diff options
author | Takashi Sakamoto <o-takashi@sakamocchi.jp> | 2025-09-17 09:03:47 +0900 |
---|---|---|
committer | Takashi Sakamoto <o-takashi@sakamocchi.jp> | 2025-09-17 09:07:03 +0900 |
commit | 582310376d6e9a8d261b682178713cdc4b251af6 (patch) | |
tree | 945b0461923af396a6c940e83ae1182596dcfe5e | |
parent | abe7159125702c734e851bc0c52b51cd446298a5 (diff) |
firewire: core: shrink critical section of fw_card spinlock in bm_work
Now fw_core_handle_bus_reset() and bm_work() are serialized. Some members
of fw_card are free to access in bm_work()
This commit shrinks critical section of fw_card spinlock in bm_work()
Link: https://lore.kernel.org/r/20250917000347.52369-4-o-takashi@sakamocchi.jp
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
-rw-r--r-- | drivers/firewire/core-card.c | 30 |
1 files changed, 8 insertions, 22 deletions
diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c index 96495392a1f6..4fcd5ce4b2ce 100644 --- a/drivers/firewire/core-card.c +++ b/drivers/firewire/core-card.c @@ -293,12 +293,8 @@ static void bm_work(struct work_struct *work) int expected_gap_count, generation, grace; bool do_reset = false; - spin_lock_irq(&card->lock); - - if (card->local_node == NULL) { - spin_unlock_irq(&card->lock); + if (card->local_node == NULL) return; - } generation = card->generation; @@ -354,8 +350,6 @@ static void bm_work(struct work_struct *work) goto pick_me; } - spin_unlock_irq(&card->lock); - rcode = fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP, irm_id, generation, SCODE_100, CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID, @@ -365,21 +359,20 @@ static void bm_work(struct work_struct *work) if (rcode == RCODE_GENERATION) return; - spin_lock_irq(&card->lock); - if (rcode == RCODE_COMPLETE) { int bm_id = be32_to_cpu(data[0]); if (generation == card->generation) { - if (bm_id != BUS_MANAGER_ID_NOT_REGISTERED) - card->bm_node_id = 0xffc0 & bm_id; - else - card->bm_node_id = local_id; + // Used by cdev layer for "struct fw_cdev_event_bus_reset". + scoped_guard(spinlock, &card->lock) { + if (bm_id != BUS_MANAGER_ID_NOT_REGISTERED) + card->bm_node_id = 0xffc0 & bm_id; + else + card->bm_node_id = local_id; + } } if (bm_id != BUS_MANAGER_ID_NOT_REGISTERED) { - spin_unlock_irq(&card->lock); - // Somebody else is BM. Only act as IRM. if (local_id == irm_id) allocate_broadcast_channel(card, generation); @@ -393,7 +386,6 @@ static void bm_work(struct work_struct *work) * some local problem. Let's try again later and hope * that the problem has gone away by then. */ - spin_unlock_irq(&card->lock); fw_schedule_bm_work(card, msecs_to_jiffies(125)); return; } @@ -415,7 +407,6 @@ static void bm_work(struct work_struct *work) * We weren't BM in the last generation, and the last * bus reset is less than 125ms ago. Reschedule this job. */ - spin_unlock_irq(&card->lock); fw_schedule_bm_work(card, msecs_to_jiffies(125)); return; } @@ -458,7 +449,6 @@ static void bm_work(struct work_struct *work) if (!root_device_is_running) { // If we haven't probed this device yet, bail out now // and let's try again once that's done. - spin_unlock_irq(&card->lock); return; } else if (root_device->cmc) { // We will send out a force root packet for this @@ -495,8 +485,6 @@ static void bm_work(struct work_struct *work) if (do_reset) { int card_gap_count = card->gap_count; - spin_unlock_irq(&card->lock); - fw_notice(card, "phy config: new root=%x, gap_count=%d\n", new_root_id, expected_gap_count); fw_send_phy_config(card, new_root_id, generation, expected_gap_count); @@ -517,8 +505,6 @@ static void bm_work(struct work_struct *work) } else { struct fw_device *root_device = fw_node_get_device(root_node); - spin_unlock_irq(&card->lock); - if (root_device && root_device->cmc) { // Make sure that the cycle master sends cycle start packets. __be32 data = cpu_to_be32(CSR_STATE_BIT_CMSTR); |