• Julian Wiedmann's avatar
    s390/qeth: call dev_close() during recovery · d4560150
    Julian Wiedmann authored
    When resetting an interface ("recovery"), qeth currently attempts to
    elide the call to dev_close(). We initially only call .ndo_close to
    quiesce the data path, and then offline & online the ccwgroup device.
    If the reset succeeded, a call to .ndo_open then resumes the data path
    along with some internal setup (dev_addr validation, RX modeset) that
    dev_open() would have usually triggered.
    dev_close() only gets called (via the close_dev worker) if the reset
    action fails.
    
    It's unclear whether this was initially done due to locking concerns, or
    rather to execute the reset transparently. Either way, temporarily
    closing the interface without dev_close() is fragile, and means we're
    susceptible to various races and unexpected behaviour. For instance:
    
    - Bypassing dev_deactivate_many() means that the qdiscs are not set to
    __QDISC_STATE_DEACTIVATED. Consequently any intermittent TX completion
    can wake up the txq, resulting in calls to .ndo_start_xmit while the
    data path is down. We have custom state checking to detect this case
    and drop such packets.
    
    - Because the IFF_UP flag doesn't reflect the interface's actual state
    during a reset, we have custom state checking in .ndo_open and
    .ndo_close to guard against invalid calls.
    
    - Considering that the reset might take a considerable amount of time
    (in particular if an IO fails and we end up waiting for its timeout), we
    _do_ want NETDEV_GOING_DOWN and NETDEV_DOWN events so that components
    like bonding, team, bridge, macvlan, vlan, ... can take appropriate
    action.
    Signed-off-by: default avatarJulian Wiedmann <jwi@linux.ibm.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    d4560150
qeth_core_main.c 170 KB