• B
    net: Set device operstate at registration time · 8f4cccbb
    Ben Hutchings 提交于
    The operstate of a device is initially IF_OPER_UNKNOWN and is updated
    asynchronously by linkwatch after each change of carrier state
    reported by the driver.  The default carrier state of a net device is
    on, and this will never be changed on drivers that do not support
    carrier detection, thus the operstate remains IF_OPER_UNKNOWN.
    
    For devices that do support carrier detection, the driver must set the
    carrier state to off initially, then poll the hardware state when the
    device is opened.  However, we must not activate linkwatch for a
    unregistered device, and commit b4730016 ('net: Do not fire linkwatch
    events until the device is registered.') ensured that we don't.  But
    this means that the operstate for many devices that support carrier
    detection remains IF_OPER_UNKNOWN when it should be IF_OPER_DOWN.
    
    The same issue exists with the dormant state.
    
    The proper initialisation sequence, avoiding a race with opening of
    the device, is:
    
            rtnl_lock();
            rc = register_netdevice(dev);
            if (rc)
                    goto out_unlock;
            netif_carrier_off(dev); /* or netif_dormant_on(dev) */
            rtnl_unlock();
    
    but it seems silly that this should have to be repeated in so many
    drivers.  Further, the operstate seen immediately after opening the
    device may still be IF_OPER_UNKNOWN due to the asynchronous nature of
    linkwatch.
    
    Commit 22604c86 ('net: Fix for initial link state in 2.6.28') attempted
    to fix this by setting the operstate synchronously, but it was
    reverted as it could lead to deadlock.
    
    This initialises the operstate synchronously at registration time
    only.
    Signed-off-by: NBen Hutchings <bhutchings@solarflare.com>
    Signed-off-by: NDavid S. Miller <davem@davemloft.net>
    8f4cccbb
dev.c 162.0 KB