Re: [PATCH 2/2] usb: gadget: f_ncm: add support for scatter/gather SKB to enable GSO

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

Jussi Kivilinna <jussi.kivilinna@xxxxxxxxxxx> writes:
>> Felipe Balbi <balbi@xxxxxxxxxx> writes:
>>>>>> Enabling SG allows enabling GSO (generic segmentation offload) feature
>>>>>> of linux networking layer. This increases TCP throughput with NCM
>>>>>> on Cortex-A15+USB3380 based device from 300 Mbit/s to 1.1 Gbit/s.
>>>>>>
>>>>>> Signed-off-by: Jussi Kivilinna <jussi.kivilinna@xxxxxxxxxxx>
>>>>>
>>>>> this is AWESOME!! :-) But here's the thing, any chance we can build this
>>>>> in u_ether.c ? Also, NETIF_F_SG should be conditional on
>>>>> gadget->sg_supported so that we don't break UDCs that don't support
>>>>> sglists.
>>>>>
>>>>
>>>> Actually, no sglists are passed to UDC. Reason why this work
>>>> with minimal changes for NCM is that NCM does tx buffering
>>>> in its wrap function.. 'ncm_wrap_ntb' copies input skbuffs to
>>>> larger skbuff, so enabling SG is  only matter of changing that
>>>> skbuff data copy from 'memcpy' to 'skb_copy_bits' (and changing
>>>> CRC calculation work with skbuff fragments). Since NCM already
>>>> does copying, SG can be enabled for NCM without extra overhead.
>>>
>>> aha, understood. Now what if we skip copying altogether? If we have an
>>> sg and a UDC that supports sg (gadget->sg_supported = 1), then we can
>>> avoid copying, right?
>> 
>> perhaps this is the crud of the change (still need to check for
>> sg_supported)?
>> 
>> diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c
>> index 5f562c1ec795..f3497cba32ec 100644
>> --- a/drivers/usb/gadget/function/u_ether.c
>> +++ b/drivers/usb/gadget/function/u_ether.c
>> @@ -235,7 +235,7 @@ rx_submit(struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags)
>>          */
>>         skb_reserve(skb, NET_IP_ALIGN);
>>  
>> -       req->buf = skb->data;
>> +       req->num_sgs = skb_to_sgvec(skb, req->sg, 0, skb->len);
>>         req->length = size;
>>         req->complete = rx_complete;
>>         req->context = skb;
>> 
>
> I did experiment with this, but cannot fully test it without
> sg_supported UDC. Also, wrapper functions need to be reviewed
> to make sure they work with non-linear skbuffs. Seems that EEM
> wrapper had problem with SG, probably because it tries to add
> CRC at the skbuff tail. Below is patch which I've tested for
> now. It applies on top of the earlier NCM SG patch.
>
> -Jussi
>
> ---
> [PATCH] [RFC] usb: gadget: u_ether: enable NETIF_F_SG for networking gadgets
>
> Signed-off-by: Jussi Kivilinna <jussi.kivilinna@xxxxxxxxxxx>

I tested this patch on top of previous two patches. It works fine for a
while, but then starts failing. No idea yet why it fails. I'll try to
debug this for a while longer.

> @@ -363,6 +364,14 @@ static int prealloc(struct list_head *list, struct usb_ep *ep, unsigned n)
>  	}
>  	while (i--) {
>  		req = usb_ep_alloc_request(ep, GFP_ATOMIC);
> +		if (alloc_sg && req) {
> +			req->sg = kmalloc(sizeof(*req->sg) *
> +					  (MAX_SKB_FRAGS + 2), GFP_ATOMIC);

how about:

	kmalloc_array(MAX_SKB_FRAGS + 2, sizeof(*req->sg), GFP_ATOMIC)

> @@ -376,6 +385,8 @@ extra:
>  
>  		next = req->list.next;
>  		list_del(&req->list);
> +		if (req->sg)
> +			kfree(req->sg);

the check here is unnecessary. Just kfree(req->sg) :-)

> @@ -391,10 +402,11 @@ static int alloc_requests(struct eth_dev *dev, struct gether *link, unsigned n)
>  	int	status;
>  
>  	spin_lock(&dev->req_lock);
> -	status = prealloc(&dev->tx_reqs, link->in_ep, n);
> +	status = prealloc(&dev->tx_reqs, link->in_ep, n,
> +			  dev->gadget->sg_supported);
>  	if (status < 0)
>  		goto fail;
> -	status = prealloc(&dev->rx_reqs, link->out_ep, n);
> +	status = prealloc(&dev->rx_reqs, link->out_ep, n, false);

why don't we want sglist for rx?

-- 
balbi

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux