On Thu, 2010-11-11 at 17:07 -0800, Joe Eykholt wrote:
> 
> On 11/11/10 5:00 PM, Nicholas A. Bellinger wrote:
> > On Wed, 2010-11-10 at 17:44 -0800, Kiran Patil wrote:
> >> From: Kiran Patil <[email protected]>
> >>
> >> Problem: Existing implementation of TCM/LIO target isn't taking advantage 
> >> of underlying HW (NIC)
> >>          Large Send Offload (LSO) feature. Unable to use non-linear SKBs 
> >> for CONTROL_NONSG CDBs
> >>          such as INQUIRY, etc...
> >>
> >> Fix:     Enhance function (ft_queue_data_in) which sends data back to 
> >> initiator to make use of
> >>          LSO feature of underlying HW and fix the issues related to 
> >> CONTROL_NONSG, where code
> >>          was unable to map TCM provided buffer (t_task_buf) as non-linear 
> >> SKB.
> >>
> >> Technical Details: Enhancement benefits in all threee cases , use_sg, mem, 
> >> and task_buf. This changes
> >>          are applicable only for all CDBs (DATA/CONTROL SG/NONSG).
> >>          - Addressed comments from Joe w.r.t checking and making use_sg = 
> >> 0 only
> >>            for DATA_SG whereas it is applicale for 
> >> CONTROL_SG/CONTROL_NONSG.
> >>          - Made the prink rate limited (in case where "unable to send 
> >> frame")
> >>          - Fixed 2 issues/bugs related to CONTROL_NONSG and non-linear SKB.
> >>          - Added a BUG_ON(!page)
> >>
> >> Dependencies: This depends on TCM and Joe's FC4 patches for TCM
> >>
> >> Signed-off-by: Kiran Patil <[email protected]>
> >> Signed-off-by: Yi Zou <[email protected]>
> > 
> > Btw, I think this patch looks good guys..
> > 
> > Joe, can I get your ACK and get this merged into lio-core-2.6.git for
> > testing..?
> 
> I reviewed it but didn't test it.  Based on that, I'll give my ack.
> 
> Acked-by: Joe Eykholt <[email protected]>
> 

Thanks Joe!  Commited as:

[tcm_fc_ddp_offload b035e31] TCM/OpenFCoE : Added Large Send Offload
 Author: Kiran Patil <[email protected]>
 1 files changed, 37 insertions(+), 7 deletions(-)

and pushed into lio-core-2.6.git/tcm_fc_ddp_offload for testing along
with the latest lio-4.0 changes from hch.

Thanks Kiran and Yi!

--nab


> 
> > 
> > Thanks!
> > 
> > --nab
> > 
> >> ---
> >>
> >>  drivers/target/tcm_fc/tfc_io.c |   44 
> >> ++++++++++++++++++++++++++++++++++------
> >>  1 files changed, 37 insertions(+), 7 deletions(-)
> >>
> >> diff --git a/drivers/target/tcm_fc/tfc_io.c 
> >> b/drivers/target/tcm_fc/tfc_io.c
> >> index e77a45a..4c3c0ef 100644
> >> --- a/drivers/target/tcm_fc/tfc_io.c
> >> +++ b/drivers/target/tcm_fc/tfc_io.c
> >> @@ -78,6 +78,7 @@ int ft_queue_data_in(struct se_cmd *se_cmd)
> >>    size_t frame_len = 0;
> >>    size_t mem_len;
> >>    size_t tlen;
> >> +  size_t off_in_page;
> >>    struct page *page;
> >>    int use_sg;
> >>    int error;
> >> @@ -111,7 +112,6 @@ int ft_queue_data_in(struct se_cmd *se_cmd)
> >>  
> >>    /* no scatter/gather in skb for odd word length due to fc_seq_send() */
> >>    use_sg = !(remaining % 4);
> >> -  use_sg = 0;     /* XXX to test the non-sg path */
> >>  
> >>    while (remaining) {
> >>            if (!mem_len) {
> >> @@ -123,7 +123,13 @@ int ft_queue_data_in(struct se_cmd *se_cmd)
> >>                    page = mem->se_page;
> >>            }
> >>            if (!frame_len) {
> >> -                  frame_len = cmd->sess->max_frame;
> >> +                  /*
> >> +                   * If lport's has capability of Large Send Offload LSO)
> >> +                   * , then allow 'frame_len' to be as big as 'lso_max'
> >> +                   * if indicated transfer length is >= lport->lso_max
> >> +                   */
> >> +                  frame_len = (lport->seq_offload) ? lport->lso_max :
> >> +                                                    cmd->sess->max_frame;
> >>                    frame_len = min(frame_len, remaining);
> >>                    fp = fc_frame_alloc(lport, use_sg ? 0 : frame_len);
> >>                    if (!fp)
> >> @@ -131,16 +137,34 @@ int ft_queue_data_in(struct se_cmd *se_cmd)
> >>                    to = fc_frame_payload_get(fp, 0);
> >>                    fh_off = frame_off;
> >>                    frame_off += frame_len;
> >> +                  /*
> >> +                   * Setup the frame's max payload which is used by base
> >> +                   * driver to indicate HW about max frame size, so that
> >> +                   * HW can do fragmentation appropriately based on
> >> +                   * "gso_max_size" of underline netdev.
> >> +                   */
> >> +                  fr_max_payload(fp) = cmd->sess->max_frame;
> >>            }
> >>            tlen = min(mem_len, frame_len);
> >>  
> >>            if (use_sg) {
> >> -                  if (!mem)
> >> -                          page = virt_to_page(task->t_task_buf + mem_off);
> >> +                  if (!mem) {
> >> +                          BUG_ON(!task->t_task_buf);
> >> +                          page_addr = task->t_task_buf + mem_off;
> >> +                          /*
> >> +                           * In this case, offset is 'offset_in_page' of
> >> +                           * (t_task_buf + mem_off) instead of 'mem_off'.
> >> +                           */
> >> +                          off_in_page = offset_in_page(page_addr);
> >> +                          page = virt_to_page(page_addr);
> >> +                          tlen = min(tlen, PAGE_SIZE - off_in_page);
> >> +                  } else
> >> +                          off_in_page = mem_off;
> >> +                  BUG_ON(!page);
> >>                    get_page(page);
> >>                    skb_fill_page_desc(fp_skb(fp),
> >>                                       skb_shinfo(fp_skb(fp))->nr_frags,
> >> -                                     page, mem_off, tlen);
> >> +                                     page, off_in_page, tlen);
> >>                    fr_len(fp) += tlen;
> >>                    fp_skb(fp)->data_len += tlen;
> >>                    fp_skb(fp)->truesize +=
> >> @@ -167,7 +191,8 @@ int ft_queue_data_in(struct se_cmd *se_cmd)
> >>            frame_len -= tlen;
> >>            remaining -= tlen;
> >>  
> >> -          if (frame_len)
> >> +          if (frame_len &&
> >> +              (skb_shinfo(fp_skb(fp))->nr_frags < FC_FRAME_SG_LEN))
> >>                    continue;
> >>            if (!remaining)
> >>                    f_ctl |= FC_FC_END_SEQ;
> >> @@ -175,8 +200,13 @@ int ft_queue_data_in(struct se_cmd *se_cmd)
> >>                           FC_TYPE_FCP, f_ctl, fh_off);
> >>            error = lport->tt.seq_send(lport, cmd->seq, fp);
> >>            if (error) {
> >> -                  WARN_ON(1);
> >>                    /* XXX For now, initiator will retry */
> >> +                  if (printk_ratelimit())
> >> +                          printk(KERN_ERR "%s: Failed to send frame %p, "
> >> +                                          "xid <0x%x>, remaining <0x%x>, "
> >> +                                          "lso_max <0x%x>\n",
> >> +                                          __func__, fp, ep->xid,
> >> +                                          remaining, lport->lso_max);
> >>            }
> >>    }
> >>    return ft_queue_status(se_cmd);
> >>
> >> _______________________________________________
> >> devel mailing list
> >> [email protected]
> >> http://www.open-fcoe.org/mailman/listinfo/devel
> > 

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

Reply via email to