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