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>
This commit is contained in:
parent
b86788658b
commit
5d73bea2d3
1 changed files with 7 additions and 2 deletions
|
@ -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.
|
* At this point, we have the exchange held.
|
||||||
* Find or create the sequence.
|
* 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
|
* sending RSP, hence write request on other
|
||||||
* end never finishes.
|
* end never finishes.
|
||||||
*/
|
*/
|
||||||
spin_lock_bh(&ep->ex_lock);
|
|
||||||
sp->ssb_stat |= SSB_ST_RESP;
|
sp->ssb_stat |= SSB_ST_RESP;
|
||||||
sp->id = fh->fh_seq_id;
|
sp->id = fh->fh_seq_id;
|
||||||
spin_unlock_bh(&ep->ex_lock);
|
|
||||||
} else {
|
} else {
|
||||||
|
spin_unlock_bh(&ep->ex_lock);
|
||||||
|
|
||||||
/* sequence/exch should exist */
|
/* sequence/exch should exist */
|
||||||
reject = FC_RJT_SEQ_ID;
|
reject = FC_RJT_SEQ_ID;
|
||||||
goto rel;
|
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)
|
if (f_ctl & FC_FC_SEQ_INIT)
|
||||||
ep->esb_stat |= ESB_ST_SEQ_INIT;
|
ep->esb_stat |= ESB_ST_SEQ_INIT;
|
||||||
|
spin_unlock_bh(&ep->ex_lock);
|
||||||
|
|
||||||
fr_seq(fp) = sp;
|
fr_seq(fp) = sp;
|
||||||
out:
|
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);
|
f_ctl = ntoh24(fh->fh_f_ctl);
|
||||||
fr_seq(fp) = sp;
|
fr_seq(fp) = sp;
|
||||||
|
|
||||||
|
spin_lock_bh(&ep->ex_lock);
|
||||||
if (f_ctl & FC_FC_SEQ_INIT)
|
if (f_ctl & FC_FC_SEQ_INIT)
|
||||||
ep->esb_stat |= ESB_ST_SEQ_INIT;
|
ep->esb_stat |= ESB_ST_SEQ_INIT;
|
||||||
|
spin_unlock_bh(&ep->ex_lock);
|
||||||
|
|
||||||
if (fc_sof_needs_ack(sof))
|
if (fc_sof_needs_ack(sof))
|
||||||
fc_seq_send_ack(sp, fp);
|
fc_seq_send_ack(sp, fp);
|
||||||
|
|
Loading…
Add table
Reference in a new issue