[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>

authored by Samuel Ortiz and committed by David S. Miller 3958fb34 9d0f7d29

+21 -23
+20 -23
drivers/net/irda/irda-usb.c
··· 441 441 goto drop; 442 442 } 443 443 444 - /* Make sure there is room for IrDA-USB header. The actual 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 - } 444 + memcpy(self->tx_buff + self->header_length, skb->data, skb->len); 455 445 456 446 /* Change setting for next frame */ 457 - 458 447 if (self->capability & IUC_STIR421X) { 459 448 __u8 turnaround_time; 460 - __u8* frame; 449 + __u8* frame = self->tx_buff; 461 450 turnaround_time = get_turnaround_time( skb ); 462 - frame= skb_push(skb, self->header_length); 463 451 irda_usb_build_header(self, frame, 0); 464 452 frame[2] = turnaround_time; 465 453 if ((skb->len != 0) && ··· 460 472 frame[1] = 0; 461 473 } 462 474 } else { 463 - irda_usb_build_header(self, skb_push(skb, self->header_length), 0); 475 + irda_usb_build_header(self, self->tx_buff, 0); 464 476 } 465 477 466 478 /* FIXME: Make macro out of this one */ 467 479 ((struct irda_skb_cb *)skb->cb)->context = self; 468 480 469 - usb_fill_bulk_urb(urb, self->usbdev, 481 + usb_fill_bulk_urb(urb, self->usbdev, 470 482 usb_sndbulkpipe(self->usbdev, self->bulk_out_ep), 471 - skb->data, IRDA_SKB_MAX_MTU, 483 + self->tx_buff, skb->len + self->header_length, 472 484 write_bulk_callback, skb); 473 - urb->transfer_buffer_length = skb->len; 485 + 474 486 /* This flag (URB_ZERO_PACKET) indicates that what we send is not 475 487 * a continuous stream of data but separate packets. 476 488 * In this case, the USB layer will insert an empty USB frame (TD) ··· 1443 1455 /* Remove the speed buffer */ 1444 1456 kfree(self->speed_buff); 1445 1457 self->speed_buff = NULL; 1458 + 1459 + kfree(self->tx_buff); 1460 + self->tx_buff = NULL; 1446 1461 } 1447 1462 1448 1463 /********************** USB CONFIG SUBROUTINES **********************/ ··· 1744 1753 1745 1754 memset(self->speed_buff, 0, IRDA_USB_SPEED_MTU); 1746 1755 1756 + self->tx_buff = kzalloc(IRDA_SKB_MAX_MTU + self->header_length, 1757 + GFP_KERNEL); 1758 + if (self->tx_buff == NULL) 1759 + goto err_out_4; 1760 + 1747 1761 ret = irda_usb_open(self); 1748 1762 if (ret) 1749 - goto err_out_4; 1763 + goto err_out_5; 1750 1764 1751 1765 IRDA_MESSAGE("IrDA: Registered device %s\n", net->name); 1752 1766 usb_set_intfdata(intf, self); ··· 1762 1766 self->needspatch = (ret < 0); 1763 1767 if (self->needspatch) { 1764 1768 IRDA_ERROR("STIR421X: Couldn't upload patch\n"); 1765 - goto err_out_5; 1769 + goto err_out_6; 1766 1770 } 1767 1771 1768 1772 /* replace IrDA class descriptor with what patched device is now reporting */ 1769 1773 irda_desc = irda_usb_find_class_desc (self->usbintf); 1770 1774 if (irda_desc == NULL) { 1771 1775 ret = -ENODEV; 1772 - goto err_out_5; 1776 + goto err_out_6; 1773 1777 } 1774 1778 if (self->irda_desc) 1775 1779 kfree (self->irda_desc); ··· 1778 1782 } 1779 1783 1780 1784 return 0; 1781 - 1782 - err_out_5: 1785 + err_out_6: 1783 1786 unregister_netdev(self->netdev); 1787 + err_out_5: 1788 + kfree(self->tx_buff); 1784 1789 err_out_4: 1785 1790 kfree(self->speed_buff); 1786 1791 err_out_3:
+1
drivers/net/irda/irda-usb.h
··· 156 156 struct irlap_cb *irlap; /* The link layer we are binded to */ 157 157 struct qos_info qos; 158 158 char *speed_buff; /* Buffer for speed changes */ 159 + char *tx_buff; 159 160 160 161 struct timeval stamp; 161 162 struct timeval now;