lkml.org 
[lkml]   [2022]   [Aug]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.19 175/365] iavf: Fix deadlock in initialization
    Date
    From: Ivan Vecera <ivecera@redhat.com>

    commit cbe9e51126305832cf407ee6bb556ce831488ffe upstream.

    Fix deadlock that occurs when iavf interface is a part of failover
    configuration.

    1. Mutex crit_lock is taken at the beginning of iavf_watchdog_task()
    2. Function iavf_init_config_adapter() is called when adapter
    state is __IAVF_INIT_CONFIG_ADAPTER
    3. iavf_init_config_adapter() calls register_netdevice() that emits
    NETDEV_REGISTER event
    4. Notifier function failover_event() then calls
    net_failover_slave_register() that calls dev_open()
    5. dev_open() calls iavf_open() that tries to take crit_lock in
    end-less loop

    Stack trace:
    ...
    [ 790.251876] usleep_range_state+0x5b/0x80
    [ 790.252547] iavf_open+0x37/0x1d0 [iavf]
    [ 790.253139] __dev_open+0xcd/0x160
    [ 790.253699] dev_open+0x47/0x90
    [ 790.254323] net_failover_slave_register+0x122/0x220 [net_failover]
    [ 790.255213] failover_slave_register.part.7+0xd2/0x180 [failover]
    [ 790.256050] failover_event+0x122/0x1ab [failover]
    [ 790.256821] notifier_call_chain+0x47/0x70
    [ 790.257510] register_netdevice+0x20f/0x550
    [ 790.258263] iavf_watchdog_task+0x7c8/0xea0 [iavf]
    [ 790.259009] process_one_work+0x1a7/0x360
    [ 790.259705] worker_thread+0x30/0x390

    To fix the situation we should check the current adapter state after
    first unsuccessful mutex_trylock() and return with -EBUSY if it is
    __IAVF_INIT_CONFIG_ADAPTER.

    Fixes: 226d528512cf ("iavf: fix locking of critical sections")
    Signed-off-by: Ivan Vecera <ivecera@redhat.com>
    Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
    Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/net/ethernet/intel/iavf/iavf_main.c | 11 ++++++++++-
    1 file changed, 10 insertions(+), 1 deletion(-)

    --- a/drivers/net/ethernet/intel/iavf/iavf_main.c
    +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
    @@ -3989,8 +3989,17 @@ static int iavf_open(struct net_device *
    return -EIO;
    }

    - while (!mutex_trylock(&adapter->crit_lock))
    + while (!mutex_trylock(&adapter->crit_lock)) {
    + /* If we are in __IAVF_INIT_CONFIG_ADAPTER state the crit_lock
    + * is already taken and iavf_open is called from an upper
    + * device's notifier reacting on NETDEV_REGISTER event.
    + * We have to leave here to avoid dead lock.
    + */
    + if (adapter->state == __IAVF_INIT_CONFIG_ADAPTER)
    + return -EBUSY;
    +
    usleep_range(500, 1000);
    + }

    if (adapter->state != __IAVF_DOWN) {
    err = -EBUSY;

    \
     
     \ /
      Last update: 2022-08-23 10:43    [W:2.840 / U:0.104 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site