Skip to content

Commit

Permalink
[SCSI] qla2xxx: Test and clear FCPORT_UPDATE_NEEDED atomically.
Browse files Browse the repository at this point in the history
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: David Jeffery <djeffery@redhat.com>
Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com>
Cc: stable@vger.kernel.org
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
  • Loading branch information
David Jeffery authored and James Bottomley committed Nov 30, 2012
1 parent 63ea923 commit a394aac
Showing 1 changed file with 2 additions and 2 deletions.
4 changes: 2 additions & 2 deletions drivers/scsi/qla2xxx/qla_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -4505,9 +4505,9 @@ qla2x00_do_dpc(void *data)
"ISP abort end.\n");
}

if (test_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags)) {
if (test_and_clear_bit(FCPORT_UPDATE_NEEDED,
&base_vha->dpc_flags)) {
qla2x00_update_fcports(base_vha);
clear_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags);
}

if (test_bit(SCR_PENDING, &base_vha->dpc_flags)) {
Expand Down

0 comments on commit a394aac

Please sign in to comment.