From 27c7acf22047fbe4ec4cc36b7c2610dba227697c Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 5 May 2010 23:57:37 +0200 Subject: USB: serial: reimplement generic fifo-based writes Reimplement fifo-based writes in the generic driver using a multiple pre-allocated urb scheme. In contrast to multi-urb writes, no allocations (of urbs or buffers) are made during run-time and there is less pressure on the host stack queues as currently only two urbs are used (implementation is generic and can handle more than two urbs as well, though). Initial tests using ftdi_sio show that the implementation achieves the same (maximum) throughput at high baudrates as multi-urb writes. The CPU usage is much lower than for multi-urb writes for small write requests and only slightly higher for large (e.g. 2k) requests (due to extra copy via fifo?). Also outperforms multi-urb writes for small write requests on an embedded arm-9 system, where multi-urb writes are CPU-bound at high baudrates (perf reveals that a lot of time is spent in the host stack enqueue function -- could perhaps be a bug as well). Keeping the original write_urb, buffer and flag for now as there are other drivers depending on them. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- include/linux/usb/serial.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'include/linux/usb') diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index a4c99ea390e7..70b6d6b28997 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -35,6 +35,9 @@ enum port_dev_state { PORT_UNREGISTERING, }; +/* USB serial flags */ +#define USB_SERIAL_WRITE_BUSY 0 + /** * usb_serial_port: structure for the specific ports of a device. * @serial: pointer back to the struct usb_serial owner of this port. @@ -60,10 +63,14 @@ enum port_dev_state { * @write_urb: pointer to the bulk out struct urb for this port. * @write_fifo: kfifo used to buffer outgoing data * @write_urb_busy: port`s writing status + * @bulk_out_buffers: pointers to the bulk out buffers for this port + * @write_urbs: pointers to the bulk out urbs for this port + * @write_urbs_free: status bitmap the for bulk out urbs * @tx_bytes: number of bytes currently in host stack queues * @tx_urbs: number of urbs currently in host stack queues * @bulk_out_endpointAddress: endpoint address for the bulk out pipe for this * port. + * @flags: usb serial port flags * @write_wait: a wait_queue_head_t used by the port. * @work: work queue entry for the line discipline waking up. * @throttled: nonzero if the read urb is inactive to throttle the device @@ -98,11 +105,16 @@ struct usb_serial_port { struct urb *write_urb; struct kfifo write_fifo; int write_urb_busy; + + unsigned char *bulk_out_buffers[2]; + struct urb *write_urbs[2]; + unsigned long write_urbs_free; __u8 bulk_out_endpointAddress; int tx_bytes; int tx_urbs; + unsigned long flags; wait_queue_head_t write_wait; struct work_struct work; char throttled; -- cgit v1.2.3