Find the answer to your Linux question:
Page 1 of 2 1 2 LastLast
Results 1 to 10 of 11
Hi, I am currently involved in developing a product which use a USB communication device as its WAN port. The product is a CPE, intended to forward TCP/UDP traffic from ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Jan 2014
    Posts
    6

    Ethernet over USB – implementing “Leaky bucket” algorithm.


    Hi,
    I am currently involved in developing a product which use a USB communication device as its WAN port.
    The product is a CPE, intended to forward TCP/UDP traffic from the USB port towards Ethernet port which is the LAN side.
    For stability reasons we want to be able to control the rate of incoming packets from USB side, regardless of size, merely PPS criteria. The easiest way to do so is using a “leaky bucket” budget based algorithm.
    Naturally we want to drop a packet as soon as possible, which means in the USB hierarchy, as close as possible to HW.
    The problem is that I can’t drop an URB without causing an error which shuts the qh.
    Is there a place I can remove incoming data if token budget is zero?
    A few details:
    1. We are using ARM 11.
    2. Kernel 2.6.39. (part of the Openwrt backfire we use)
    3. USB 2.0 high speed.

    Thanks a lot
    Guy

  2. #2
    Linux Engineer
    Join Date
    Dec 2013
    Posts
    1,366
    When you say remove do mean calling usb_unlink_urb?

  3. #3
    Just Joined!
    Join Date
    Jan 2014
    Posts
    6
    Hi,
    Thanks for the fast response.
    By remove I mean drop the packet and lose the data.
    Unfortunately I'm not that familiar with the USB hierarchy, so I'm not sure if usb_unlink_urb is the only action I should take.
    Are there any other actions I should take?
    Thanks.
    Guy

  4. #4
    Just Joined!
    Join Date
    Jan 2014
    Posts
    8
    Assuming that you do not intend to modify the kernel, the first function that is being called when a buffer arrives from USB bus is the completion callback that you register with the urb that will passed to usb_submit_urb().

  5. #5
    Just Joined!
    Join Date
    Jan 2014
    Posts
    6
    Quote Originally Posted by ianbb01 View Post
    Assuming that you do not intend to modify the kernel, the first function that is being called when a buffer arrives from USB bus is the completion callback that you register with the urb that will passed to usb_submit_urb().
    DO you mean qh_completions?
    Trying to drop the packet there caused the the usb to stop working.
    Thanks.
    Guy

  6. #6
    Just Joined!
    Join Date
    Jan 2014
    Posts
    8
    No, I meant at a higher level. qh_completions() is a part of EHCI controller driver. I don't recommend modifying the controller driver or even higher parts of the USB stack unless you are 100% sure that you know what you are doing. Note that modifying those functions will change the USB stack behavior of your kernel.

    From my experience, in order to achieve good performance you don't need to work at such low levels. What I meant is to analyze the packet in the completion callback that is passed to usb_submit_urb() and deside there whether it will be passed to the higher level or ignored.

  7. #7
    Just Joined!
    Join Date
    Jan 2014
    Posts
    6
    Hi,
    I can drop the packet at the RX_fixup (cdc_ethernet layer). It seems to be easier, but less efficient then dropping it as soon as it enters the kernel.
    Since I am working on an embedded product with specific functionality The USB will be solely used for communication.
    However, I am 100% sure that I don't know enough, hence I need to know where is the point (preferably line/code snippet) where:
    1. Packet is dropped as close as possible to entering the system.
    2. Dropping packet will not crash the USB.
    Thanks a lot, I really appreciate your help.
    Guy

  8. #8
    Just Joined!
    Join Date
    Jan 2014
    Posts
    8
    cdc_ethernet layer is indeed too high. If you are using the usbnet driver, you can modify its source code to work at lower levels. In the source code of usbnet find the call to usb_submit_urb for IN data and find the completion callback that is executed when IN data arrives. This completion callback is the right place to do the data analysis. By a quick glance at usbnet.c I can see that rx_complete is the completion callback that you are looking for.

  9. #9
    Just Joined!
    Join Date
    Jan 2014
    Posts
    6
    Quote Originally Posted by ianbb01 View Post
    cdc_ethernet layer is indeed too high. If you are using the usbnet driver, you can modify its source code to work at lower levels. In the source code of usbnet find the call to usb_submit_urb for IN data and find the completion callback that is executed when IN data arrives. This completion callback is the right place to do the data analysis. By a quick glance at usbnet.c I can see that rx_complete is the completion callback that you are looking for.
    Hi,
    Following your advice and Looking at my code, does the following conclusions make sense?
    1. in usbnet.c file (kernel 2.639 , arm arch.)
    2. rx_complete is assigned at:
    341 usb_fill_bulk_urb (urb, dev->udev, dev->in,
    342 skb->data, size, rx_complete, skb);
    3. In rx_complete:
    3.a The swithc statement checking the urb->status will break in case 0: (success)
    3.b defer_bh should be always called.
    3.c if I am over my budget jus skip the rx_submit ?

    Are ther any counters/memory allocations I should handle?

    Thanks a lot
    Guy.

  10. #10
    Just Joined!
    Join Date
    Jan 2014
    Posts
    8
    Quote Originally Posted by cpe_dev View Post
    Hi,
    Following your advice and Looking at my code, does the following conclusions make sense?
    1. in usbnet.c file (kernel 2.639 , arm arch.)
    2. rx_complete is assigned at:
    341 usb_fill_bulk_urb (urb, dev->udev, dev->in,
    342 skb->data, size, rx_complete, skb);
    3. In rx_complete:
    3.a The swithc statement checking the urb->status will break in case 0: (success)
    3.b defer_bh should be always called.
    3.c if I am over my budget jus skip the rx_submit ?

    Are ther any counters/memory allocations I should handle?

    Thanks a lot
    Guy.
    Hi Guy,

    I am not familiar with usbnet as deeply to tell you whether this is the right solution, however this is the right direction.

    Ian

Page 1 of 2 1 2 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •