diff options
author | Bart Van Assche <bvanassche@acm.org> | 2013-08-14 11:37:08 -0400 |
---|---|---|
committer | Robert Love <robert.w.love@intel.com> | 2013-09-04 16:23:38 -0400 |
commit | 5d73bea2d3a004698d16ba5face89f0bef383e76 (patch) | |
tree | a652a9094b2f4bb3d9398bf3da3497c2af1c3f8f /drivers/scsi/libfc | |
parent | b86788658be425a5454246a954721d9122d2b3d6 (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.c | 9 |
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; |
1035 | out: | 1037 | out: |
@@ -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); |