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); |
