From 5d73bea2d3a004698d16ba5face89f0bef383e76 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 14 Aug 2013 15:37:08 +0000 Subject: [PATCH] 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 Cc: Neil Horman Signed-off-by: Robert Love --- 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 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, } } + spin_lock_bh(&ep->ex_lock); /* * At this point, we have the exchange held. * Find or create the sequence. @@ -1015,11 +1016,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; @@ -1030,6 +1031,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: @@ -1479,8 +1481,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); -- 2.39.2