• David Jeffery's avatar
    [SCSI] qla2xxx: Test and clear FCPORT_UPDATE_NEEDED atomically. · a394aac8
    David Jeffery authored
    When the qla2xxx driver loses access to multiple, remote ports, there is a race
    condition which can occur which will keep the request stuck on a scsi request
    queue indefinitely.
    
    This bad state occurred do to a race condition with how the FCPORT_UPDATE_NEEDED
    bit is set in qla2x00_schedule_rport_del(), and how it is cleared in
    qla2x00_do_dpc().  The problem port has its drport pointer set, but it has never
    been processed by the driver to inform the fc transport that the port has been
    lost.  qla2x00_schedule_rport_del() sets drport, and then sets the
    FCPORT_UPDATE_NEEDED bit.  In qla2x00_do_dpc(), the port lists are walked and
    any drport pointer is handled and the fc transport informed of the port loss,
    then the FCPORT_UPDATE_NEEDED bit is cleared.  This leaves a race where the
    dpc thread is processing one port removal, another port removal is marked
    with a call to qla2x00_schedule_rport_del(), and the dpc thread clears the
    bit for both removals, even though only the first removal was actually
    handled.  Until another event occurs to set FCPORT_UPDATE_NEEDED, the later
    port removal is never finished and qla2xxx stays in a bad state which causes
    requests to become stuck on request queues.
    
    This patch updates the driver to test and clear FCPORT_UPDATE_NEEDED
    atomically.  This ensures the port state changes are processed and not lost.
    Signed-off-by: default avatarDavid Jeffery <djeffery@redhat.com>
    Signed-off-by: default avatarChad Dupuis <chad.dupuis@qlogic.com>
    Cc: stable@vger.kernel.org
    Signed-off-by: default avatarSaurav Kashyap <saurav.kashyap@qlogic.com>
    Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
    a394aac8
qla_os.c 144 KB