USB: u_bam: Copy data to host in work queue context
Currently data to host is being sent in interrupt context
instead of work queue context which might hit perforamce.
Hence move this processing to work queue context.
With standalone dataloopback test, increments in throughput numbers
are observed as follows(Mbps):
TCP uplink 29.7 53.1
TCP downlink 29.8 53.7
UDP uplink 16.7 22.7
UDP downlink 20.8 24.2
Change-Id: I72ae2ccb0aee43db5a69514a002eba78ae647573
Signed-off-by: Vijayavardhan Vennapusa <vvreddy@codeaurora.org>
diff --git a/drivers/usb/gadget/u_bam.c b/drivers/usb/gadget/u_bam.c
index 4f380df..df0646f 100644
--- a/drivers/usb/gadget/u_bam.c
+++ b/drivers/usb/gadget/u_bam.c
@@ -96,6 +96,7 @@
struct gbam_port *port;
struct work_struct write_tobam_w;
+ struct work_struct write_tohost_w;
struct usb_request *rx_req;
struct usb_request *tx_req;
@@ -176,15 +177,19 @@
/*--------------------------------------------- */
/*------------data_path----------------------------*/
-static void gbam_write_data_tohost(struct gbam_port *port)
+static void gbam_write_data_tohost(struct work_struct *w)
{
unsigned long flags;
- struct bam_ch_info *d = &port->data_ch;
+ struct bam_ch_info *d;
+ struct gbam_port *port;
struct sk_buff *skb;
int ret;
struct usb_request *req;
struct usb_ep *ep;
+ d = container_of(w, struct bam_ch_info, write_tohost_w);
+ port = d->port;
+
spin_lock_irqsave(&port->port_lock_dl, flags);
if (!port->port_usb) {
spin_unlock_irqrestore(&port->port_lock_dl, flags);
@@ -261,7 +266,7 @@
__skb_queue_tail(&d->tx_skb_q, skb);
spin_unlock_irqrestore(&port->port_lock_dl, flags);
- gbam_write_data_tohost(port);
+ queue_work(gbam_wq, &d->write_tohost_w);
}
void gbam_data_write_done(void *p, struct sk_buff *skb)
@@ -370,7 +375,7 @@
list_add_tail(&req->list, &d->tx_idle);
spin_unlock(&port->port_lock_dl);
- gbam_write_data_tohost(port);
+ queue_work(gbam_wq, &d->write_tohost_w);
}
static void
@@ -867,6 +872,7 @@
INIT_LIST_HEAD(&d->tx_idle);
INIT_LIST_HEAD(&d->rx_idle);
INIT_WORK(&d->write_tobam_w, gbam_data_write_tobam);
+ INIT_WORK(&d->write_tohost_w, gbam_write_data_tohost);
skb_queue_head_init(&d->tx_skb_q);
skb_queue_head_init(&d->rx_skb_q);
d->id = bam_ch_ids[portno];