mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] USB speedtouch: send path optimization
@ 2003-03-10  9:38 Duncan Sands
  2003-03-12  1:02 ` Greg KH
  0 siblings, 1 reply; 2+ messages in thread
From: Duncan Sands @ 2003-03-10  9:38 UTC (permalink / raw)
  To: linux-usb-users; +Cc: Greg KH, linux-kernel

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! :)


 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 10 10:35:23 2003
+++ b/drivers/usb/misc/speedtouch.c	Mon Mar 10 10:35:23 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");


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] USB speedtouch: send path optimization
  2003-03-10  9:38 [PATCH] USB speedtouch: send path optimization Duncan Sands
@ 2003-03-12  1:02 ` Greg KH
  0 siblings, 0 replies; 2+ messages in thread
From: Greg KH @ 2003-03-12  1:02 UTC (permalink / raw)
  To: Duncan Sands; +Cc: linux-usb-users, linux-kernel

On Mon, Mar 10, 2003 at 10:38:52AM +0100, Duncan Sands wrote:
> 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! :)

Applied, thanks.

greg k-h

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2003-03-12  1:02 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-03-10  9:38 [PATCH] USB speedtouch: send path optimization Duncan Sands
2003-03-12  1:02 ` Greg KH

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®