summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libfc
diff options
context:
space:
mode:
authorBart Van Assche <bvanassche@acm.org>2013-08-14 11:37:08 -0400
committerRobert Love <robert.w.love@intel.com>2013-09-04 16:23:38 -0400
commit5d73bea2d3a004698d16ba5face89f0bef383e76 (patch)
treea652a9094b2f4bb3d9398bf3da3497c2af1c3f8f /drivers/scsi/libfc
parentb86788658be425a5454246a954721d9122d2b3d6 (diff)
libfc: Protect ep->esb_stat changes via ex_lock
This patch avoids that the WARN_ON(!(ep->esb_stat & ESB_ST_SEQ_INIT)) statement in fc_seq_send_locked() gets triggered sporadically when running FCoE target code due to concurrent ep->esb_stat modifications. Signed-off-by: Bart Van Assche <bvanassche@acm.org> Cc: Neil Horman <nhorman@tuxdriver.com> Signed-off-by: Robert Love <robert.w.love@intel.com>
Diffstat (limited to 'drivers/scsi/libfc')
-rw-r--r--drivers/scsi/libfc/fc_exch.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index 7000203845bd..bc0aba4fabb4 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -988,6 +988,7 @@ static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct fc_lport *lport,
988 } 988 }
989 } 989 }
990 990
991 spin_lock_bh(&ep->ex_lock);
991 /* 992 /*
992 * At this point, we have the exchange held. 993 * At this point, we have the exchange held.
993 * Find or create the sequence. 994 * Find or create the sequence.
@@ -1015,11 +1016,11 @@ static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct fc_lport *lport,
1015 * sending RSP, hence write request on other 1016 * sending RSP, hence write request on other
1016 * end never finishes. 1017 * end never finishes.
1017 */ 1018 */
1018 spin_lock_bh(&ep->ex_lock);
1019 sp->ssb_stat |= SSB_ST_RESP; 1019 sp->ssb_stat |= SSB_ST_RESP;
1020 sp->id = fh->fh_seq_id; 1020 sp->id = fh->fh_seq_id;
1021 spin_unlock_bh(&ep->ex_lock);
1022 } else { 1021 } else {
1022 spin_unlock_bh(&ep->ex_lock);
1023
1023 /* sequence/exch should exist */ 1024 /* sequence/exch should exist */
1024 reject = FC_RJT_SEQ_ID; 1025 reject = FC_RJT_SEQ_ID;
1025 goto rel; 1026 goto rel;
@@ -1030,6 +1031,7 @@ static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct fc_lport *lport,
1030 1031
1031 if (f_ctl & FC_FC_SEQ_INIT) 1032 if (f_ctl & FC_FC_SEQ_INIT)
1032 ep->esb_stat |= ESB_ST_SEQ_INIT; 1033 ep->esb_stat |= ESB_ST_SEQ_INIT;
1034 spin_unlock_bh(&ep->ex_lock);
1033 1035
1034 fr_seq(fp) = sp; 1036 fr_seq(fp) = sp;
1035out: 1037out:
@@ -1479,8 +1481,11 @@ static void fc_exch_recv_seq_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
1479 1481
1480 f_ctl = ntoh24(fh->fh_f_ctl); 1482 f_ctl = ntoh24(fh->fh_f_ctl);
1481 fr_seq(fp) = sp; 1483 fr_seq(fp) = sp;
1484
1485 spin_lock_bh(&ep->ex_lock);
1482 if (f_ctl & FC_FC_SEQ_INIT) 1486 if (f_ctl & FC_FC_SEQ_INIT)
1483 ep->esb_stat |= ESB_ST_SEQ_INIT; 1487 ep->esb_stat |= ESB_ST_SEQ_INIT;
1488 spin_unlock_bh(&ep->ex_lock);
1484 1489
1485 if (fc_sof_needs_ack(sof)) 1490 if (fc_sof_needs_ack(sof))
1486 fc_seq_send_ack(sp, fp); 1491 fc_seq_send_ack(sp, fp);