ChangeSet 1.1094.6.2, 2003/03/11 17:13:26-08:00, [EMAIL PROTECTED]

[PATCH] USB speedtouch: send path optimization

Write multiple cells in one function call, rather than one cell per
function call.  Under maximum send load, this reduces cell writing
CPU usage from 0.0095% to 0.0085% on my machine.  A 10% improvement! :)


 drivers/usb/misc/speedtouch.c |   68 +++++++++++++++++++++++++-----------------
 1 files changed, 41 insertions(+), 27 deletions(-)


diff -Nru a/drivers/usb/misc/speedtouch.c b/drivers/usb/misc/speedtouch.c
--- a/drivers/usb/misc/speedtouch.c     Mon Mar 17 11:47:32 2003
+++ b/drivers/usb/misc/speedtouch.c     Mon Mar 17 11:47:32 2003
@@ -273,39 +273,60 @@
        ctrl->aal5_trailer [7] = crc;
 }
 
-static char *udsl_write_cell (struct sk_buff *skb, char *target) {
+unsigned int udsl_write_cells (unsigned int howmany, struct sk_buff *skb, unsigned 
char **target_p) {
        struct udsl_control *ctrl = UDSL_SKB (skb);
+       unsigned char *target = *target_p;
+       unsigned int nc, ne, i;
 
-       ctrl->num_cells--;
+       dbg ("udsl_write_cells: howmany=%u, skb->len=%d, num_cells=%u, num_entire=%u, 
pdu_padding=%u", howmany, skb->len, ctrl->num_cells, ctrl->num_entire, 
ctrl->pdu_padding);
 
-       memcpy (target, ctrl->cell_header, ATM_CELL_HEADER);
-       target += ATM_CELL_HEADER;
+       nc = ctrl->num_cells;
+       ne = min (howmany, ctrl->num_entire);
 
-       if (ctrl->num_entire) {
-               ctrl->num_entire--;
+       for (i = 0; i < ne; i++) {
+               memcpy (target, ctrl->cell_header, ATM_CELL_HEADER);
+               target += ATM_CELL_HEADER;
                memcpy (target, skb->data, ATM_CELL_PAYLOAD);
                target += ATM_CELL_PAYLOAD;
                __skb_pull (skb, ATM_CELL_PAYLOAD);
-               return target;
        }
 
+       ctrl->num_entire -= ne;
+
+       if (!(ctrl->num_cells -= ne) || !(howmany -= ne))
+               goto out;
+
+       memcpy (target, ctrl->cell_header, ATM_CELL_HEADER);
+       target += ATM_CELL_HEADER;
        memcpy (target, skb->data, skb->len);
        target += skb->len;
        __skb_pull (skb, skb->len);
-
        memset (target, 0, ctrl->pdu_padding);
        target += ctrl->pdu_padding;
 
-       if (ctrl->num_cells) {
-               ctrl->pdu_padding = ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER;
-       } else {
-               memcpy (target, ctrl->aal5_trailer, ATM_AAL5_TRAILER);
-               target += ATM_AAL5_TRAILER;
-               /* set pti bit in last cell */
-               *(target + 3 - ATM_CELL_SIZE) |= 0x2;
+       if (--ctrl->num_cells) {
+               if (!--howmany) {
+                       ctrl->pdu_padding = ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER;
+                       goto out;
+               }
+
+               memcpy (target, ctrl->cell_header, ATM_CELL_HEADER);
+               target += ATM_CELL_HEADER;
+               memset (target, 0, ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER);
+               target += ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER;
+
+               if (--ctrl->num_cells)
+                       BUG();
        }
 
-       return target;
+       memcpy (target, ctrl->aal5_trailer, ATM_AAL5_TRAILER);
+       target += ATM_AAL5_TRAILER;
+       /* set pti bit in last cell */
+       *(target + 3 - ATM_CELL_SIZE) |= 0x2;
+
+out:
+       *target_p = target;
+       return nc - ctrl->num_cells;
 }
 
 
@@ -500,14 +521,12 @@
 static void udsl_process_send (unsigned long data)
 {
        struct udsl_send_buffer *buf;
-       unsigned int cells_to_write;
        int err;
        unsigned long flags;
-       unsigned int i;
        struct udsl_instance_data *instance = (struct udsl_instance_data *) data;
+       unsigned int num_written;
        struct sk_buff *skb;
        struct udsl_sender *snd;
-       unsigned char *target;
 
        dbg ("udsl_process_send entered");
 
@@ -577,16 +596,11 @@
                instance->current_buffer = buf;
        }
 
-       cells_to_write = min (buf->free_cells, UDSL_SKB (skb)->num_cells);
-       target = buf->free_start;
-
-       dbg ("writing %u cells from skb 0x%p to buffer 0x%p", cells_to_write, skb, 
buf);
+       num_written = udsl_write_cells (buf->free_cells, skb, &buf->free_start);
 
-       for (i = 0; i < cells_to_write; i++)
-               target = udsl_write_cell (skb, target);
+       dbg ("wrote %u cells from skb 0x%p to buffer 0x%p", num_written, skb, buf);
 
-       buf->free_start = target;
-       if (!(buf->free_cells -= cells_to_write)) {
+       if (!(buf->free_cells -= num_written)) {
                list_add_tail (&buf->list, &instance->filled_buffers);
                instance->current_buffer = NULL;
                dbg ("queued filled buffer");



-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open! 
Get cracking and register here for some mind boggling fun and 
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to