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 <[email protected]>
Cc: Robert Love <[email protected]>
Cc: Neil Horman <[email protected]>
---
 drivers/scsi/libfc/fc_exch.c |    9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index d147068..f7fc222 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -990,6 +990,7 @@ static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct 
fc_lport *lport,
                }
        }
 
+       spin_lock_bh(&ep->ex_lock);
        /*
         * At this point, we have the exchange held.
         * Find or create the sequence.
@@ -1017,11 +1018,11 @@ static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct 
fc_lport *lport,
                                 * sending RSP, hence write request on other
                                 * end never finishes.
                                 */
-                               spin_lock_bh(&ep->ex_lock);
                                sp->ssb_stat |= SSB_ST_RESP;
                                sp->id = fh->fh_seq_id;
-                               spin_unlock_bh(&ep->ex_lock);
                        } else {
+                               spin_unlock_bh(&ep->ex_lock);
+
                                /* sequence/exch should exist */
                                reject = FC_RJT_SEQ_ID;
                                goto rel;
@@ -1032,6 +1033,7 @@ static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct 
fc_lport *lport,
 
        if (f_ctl & FC_FC_SEQ_INIT)
                ep->esb_stat |= ESB_ST_SEQ_INIT;
+       spin_unlock_bh(&ep->ex_lock);
 
        fr_seq(fp) = sp;
 out:
@@ -1481,8 +1483,11 @@ static void fc_exch_recv_seq_resp(struct fc_exch_mgr 
*mp, struct fc_frame *fp)
 
        f_ctl = ntoh24(fh->fh_f_ctl);
        fr_seq(fp) = sp;
+
+       spin_lock_bh(&ep->ex_lock);
        if (f_ctl & FC_FC_SEQ_INIT)
                ep->esb_stat |= ESB_ST_SEQ_INIT;
+       spin_unlock_bh(&ep->ex_lock);
 
        if (fc_sof_needs_ack(sof))
                fc_seq_send_ack(sp, fp);
-- 
1.7.10.4

_______________________________________________
fcoe-devel mailing list
[email protected]
http://lists.open-fcoe.org/mailman/listinfo/fcoe-devel

Reply via email to