On 11/11/10 5:10 PM, Nicholas A. Bellinger wrote:
> 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 we fall through at this point, we should set frame_len to 0, so that
we'll get a new frame next time around the loop. Previously frame_len would
be 0 at this point, but if we limited out (very correctly) on the SG_LEN
check, then we should set frame_len to 0 here. I'm testing a similar fix
for fcst and ran into this.
>>>> 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