aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Ortiz <samuel@sortiz.org>2007-01-15 22:37:25 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2007-01-23 23:25:49 -0500
commit3958fb34ef18529c1e4a3eca44b7aaf94d4f4697 (patch)
treee7ed13bfae551ed43e530148293e889998768c35
parent9d0f7d29f38d4f7bf66d38d448a7d23e0bed9074 (diff)
[IrDA]: irda-usb TX path optimization (was Re: IrDA spams logfiles - since 2.6.19)
Since we stop using dev_alloc_skb on the IrDA TX frame, we constantly run into the case of the skb headroom being 0, and thus we call skb_cow for every IrDA TX frame. This patch uses a local buffer and memcpy the skb to it, saving us a kmalloc for each of those IrDA TX frames. Signed-off-by: Samuel Ortiz <samuel@sortiz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/irda/irda-usb.c43
-rw-r--r--drivers/net/irda/irda-usb.h1
2 files changed, 21 insertions, 23 deletions
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
index 3ca1082ec776..80cbf3f80432 100644
--- a/drivers/net/irda/irda-usb.c
+++ b/drivers/net/irda/irda-usb.c
@@ -441,25 +441,13 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
441 goto drop; 441 goto drop;
442 } 442 }
443 443
444 /* Make sure there is room for IrDA-USB header. The actual 444 memcpy(self->tx_buff + self->header_length, skb->data, skb->len);
445 * allocation will be done lower in skb_push().
446 * Also, we don't use directly skb_cow(), because it require
447 * headroom >= 16, which force unnecessary copies - Jean II */
448 if (skb_headroom(skb) < self->header_length) {
449 IRDA_DEBUG(0, "%s(), Insuficient skb headroom.\n", __FUNCTION__);
450 if (skb_cow(skb, self->header_length)) {
451 IRDA_WARNING("%s(), failed skb_cow() !!!\n", __FUNCTION__);
452 goto drop;
453 }
454 }
455 445
456 /* Change setting for next frame */ 446 /* Change setting for next frame */
457
458 if (self->capability & IUC_STIR421X) { 447 if (self->capability & IUC_STIR421X) {
459 __u8 turnaround_time; 448 __u8 turnaround_time;
460 __u8* frame; 449 __u8* frame = self->tx_buff;
461 turnaround_time = get_turnaround_time( skb ); 450 turnaround_time = get_turnaround_time( skb );
462 frame= skb_push(skb, self->header_length);
463 irda_usb_build_header(self, frame, 0); 451 irda_usb_build_header(self, frame, 0);
464 frame[2] = turnaround_time; 452 frame[2] = turnaround_time;
465 if ((skb->len != 0) && 453 if ((skb->len != 0) &&
@@ -472,17 +460,17 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
472 frame[1] = 0; 460 frame[1] = 0;
473 } 461 }
474 } else { 462 } else {
475 irda_usb_build_header(self, skb_push(skb, self->header_length), 0); 463 irda_usb_build_header(self, self->tx_buff, 0);
476 } 464 }
477 465
478 /* FIXME: Make macro out of this one */ 466 /* FIXME: Make macro out of this one */
479 ((struct irda_skb_cb *)skb->cb)->context = self; 467 ((struct irda_skb_cb *)skb->cb)->context = self;
480 468
481 usb_fill_bulk_urb(urb, self->usbdev, 469 usb_fill_bulk_urb(urb, self->usbdev,
482 usb_sndbulkpipe(self->usbdev, self->bulk_out_ep), 470 usb_sndbulkpipe(self->usbdev, self->bulk_out_ep),
483 skb->data, IRDA_SKB_MAX_MTU, 471 self->tx_buff, skb->len + self->header_length,
484 write_bulk_callback, skb); 472 write_bulk_callback, skb);
485 urb->transfer_buffer_length = skb->len; 473
486 /* This flag (URB_ZERO_PACKET) indicates that what we send is not 474 /* This flag (URB_ZERO_PACKET) indicates that what we send is not
487 * a continuous stream of data but separate packets. 475 * a continuous stream of data but separate packets.
488 * In this case, the USB layer will insert an empty USB frame (TD) 476 * In this case, the USB layer will insert an empty USB frame (TD)
@@ -1455,6 +1443,9 @@ static inline void irda_usb_close(struct irda_usb_cb *self)
1455 /* Remove the speed buffer */ 1443 /* Remove the speed buffer */
1456 kfree(self->speed_buff); 1444 kfree(self->speed_buff);
1457 self->speed_buff = NULL; 1445 self->speed_buff = NULL;
1446
1447 kfree(self->tx_buff);
1448 self->tx_buff = NULL;
1458} 1449}
1459 1450
1460/********************** USB CONFIG SUBROUTINES **********************/ 1451/********************** USB CONFIG SUBROUTINES **********************/
@@ -1753,9 +1744,14 @@ static int irda_usb_probe(struct usb_interface *intf,
1753 1744
1754 memset(self->speed_buff, 0, IRDA_USB_SPEED_MTU); 1745 memset(self->speed_buff, 0, IRDA_USB_SPEED_MTU);
1755 1746
1747 self->tx_buff = kzalloc(IRDA_SKB_MAX_MTU + self->header_length,
1748 GFP_KERNEL);
1749 if (self->tx_buff == NULL)
1750 goto err_out_4;
1751
1756 ret = irda_usb_open(self); 1752 ret = irda_usb_open(self);
1757 if (ret) 1753 if (ret)
1758 goto err_out_4; 1754 goto err_out_5;
1759 1755
1760 IRDA_MESSAGE("IrDA: Registered device %s\n", net->name); 1756 IRDA_MESSAGE("IrDA: Registered device %s\n", net->name);
1761 usb_set_intfdata(intf, self); 1757 usb_set_intfdata(intf, self);
@@ -1766,14 +1762,14 @@ static int irda_usb_probe(struct usb_interface *intf,
1766 self->needspatch = (ret < 0); 1762 self->needspatch = (ret < 0);
1767 if (self->needspatch) { 1763 if (self->needspatch) {
1768 IRDA_ERROR("STIR421X: Couldn't upload patch\n"); 1764 IRDA_ERROR("STIR421X: Couldn't upload patch\n");
1769 goto err_out_5; 1765 goto err_out_6;
1770 } 1766 }
1771 1767
1772 /* replace IrDA class descriptor with what patched device is now reporting */ 1768 /* replace IrDA class descriptor with what patched device is now reporting */
1773 irda_desc = irda_usb_find_class_desc (self->usbintf); 1769 irda_desc = irda_usb_find_class_desc (self->usbintf);
1774 if (irda_desc == NULL) { 1770 if (irda_desc == NULL) {
1775 ret = -ENODEV; 1771 ret = -ENODEV;
1776 goto err_out_5; 1772 goto err_out_6;
1777 } 1773 }
1778 if (self->irda_desc) 1774 if (self->irda_desc)
1779 kfree (self->irda_desc); 1775 kfree (self->irda_desc);
@@ -1782,9 +1778,10 @@ static int irda_usb_probe(struct usb_interface *intf,
1782 } 1778 }
1783 1779
1784 return 0; 1780 return 0;
1785 1781err_out_6:
1786err_out_5:
1787 unregister_netdev(self->netdev); 1782 unregister_netdev(self->netdev);
1783err_out_5:
1784 kfree(self->tx_buff);
1788err_out_4: 1785err_out_4:
1789 kfree(self->speed_buff); 1786 kfree(self->speed_buff);
1790err_out_3: 1787err_out_3:
diff --git a/drivers/net/irda/irda-usb.h b/drivers/net/irda/irda-usb.h
index 6b2271f18e77..e846c38224a3 100644
--- a/drivers/net/irda/irda-usb.h
+++ b/drivers/net/irda/irda-usb.h
@@ -156,6 +156,7 @@ struct irda_usb_cb {
156 struct irlap_cb *irlap; /* The link layer we are binded to */ 156 struct irlap_cb *irlap; /* The link layer we are binded to */
157 struct qos_info qos; 157 struct qos_info qos;
158 char *speed_buff; /* Buffer for speed changes */ 158 char *speed_buff; /* Buffer for speed changes */
159 char *tx_buff;
159 160
160 struct timeval stamp; 161 struct timeval stamp;
161 struct timeval now; 162 struct timeval now;