From: Kiran Patil <[email protected]>

Problem: Linux based SW target (TCM) connected to windows initiator was unable 
to satisfy
write request of size > 2K.

Fix: Existing linux implememtation of FCoE stack is expecting sequence number 
to match w.r.t
incoming framme. When DDP is used on target in response to write request from 
initiator, SW
stack is notified only when last data frame arrives and only the pakcket header 
of last data
frame is posted to NetRx queue of storage. When that last packet was processed 
in libfc:Exchange
layer, implementation was expecting sequence number to match, but in this case 
sequence number
which is embedded in FC Header is assigned by windows initaitor, hence due to 
sequence number mismatch
post-processing which shall result into sending RSP is not done. Enhanced the 
code to
utilize the sequence number of incoming last frame and process the packet so 
that, it
will eventually complete the write request by sending write response (RSP) GOOD.

Notes/Dependencies: This patch is validated using windows and linux initiator 
to make
sure, it doesn't break anything.

Signed-off-by: Kiran Patil <[email protected]>
---

 drivers/scsi/libfc/fc_exch.c |   26 ++++++++++++++++++++++++--
 1 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index 28231ba..f2e5306 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -965,8 +965,30 @@ static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct 
fc_lport *lport,
                sp = &ep->seq;
                if (sp->id != fh->fh_seq_id) {
                        atomic_inc(&mp->stats.seq_not_found);
-                       reject = FC_RJT_SEQ_ID; /* sequence/exch should exist */
-                       goto rel;
+                       if (f_ctl & FC_FC_END_SEQ) {
+                               /*
+                                * Update sequence_id based on incoming last
+                                * frame of sequence exchange. This is needed
+                                * for FCoE target where DDP has been used
+                                * on target where, stack is indicated only
+                                * about last frame's (payload _header) header.
+                                * Whereas "seq_id" which is part of
+                                * frame_header is allocated by initiator
+                                * which is totally different from "seq_id"
+                                * allocated when XFER_RDY was sent by target.
+                                * To avoid false -ve which results into not
+                                * 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 {
+                               /* sequence/exch should exist */
+                               reject = FC_RJT_SEQ_ID;
+                               goto rel;
+                       }
                }
        }
        WARN_ON(ep != fc_seq_exch(sp));

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

Reply via email to