lkml.org 
[lkml]   [2022]   [May]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.15 020/135] firewire: core: extend card->lock in fw_core_handle_bus_reset
    Date
    From: Niels Dossche <dossche.niels@gmail.com>

    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: <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>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/firewire/core-card.c | 3 +++
    drivers/firewire/core-topology.c | 9 +++------
    2 files changed, 6 insertions(+), 6 deletions(-)

    --- a/drivers/firewire/core-card.c
    +++ b/drivers/firewire/core-card.c
    @@ -668,6 +668,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);
    @@ -682,7 +683,9 @@ void fw_core_remove_card(struct fw_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);
    --- a/drivers/firewire/core-topology.c
    +++ b/drivers/firewire/core-topology.c
    @@ -375,16 +375,13 @@ static void report_found_node(struct fw_
    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)
    @@ -510,6 +507,8 @@ void fw_core_handle_bus_reset(struct fw_
    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
    @@ -521,8 +520,6 @@ void fw_core_handle_bus_reset(struct fw_
    card->bm_retries = 0;
    }

    - spin_lock_irqsave(&card->lock, flags);
    -
    card->broadcast_channel_allocated = card->broadcast_channel_auto_allocated;
    card->node_id = node_id;
    /*

    \
     
     \ /
      Last update: 2022-05-10 15:57    [W:2.130 / U:0.036 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site