USB: u_bam: Separate DL and UL data paths to improve rmnet performance

Current USB RMNET driver uses same spinlock for both DL and UL
data traffic which will hit the performance. Use seperate
spinlocks for DL and UL data traffic for improving throughput
numbers with RMNET interface.

With standalone dataloopback test, increments in throughput numbers
are observed as follows(Mbps):
TCP uplink  	29.7	 55.7
TCP downlink	29.8	 56.8
UDP uplink      16.7     27.8
UDP downlink	20.8	 25.7

Change-Id: I0372aa02940a4331609879a23608cdb15a83bd22
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 fb850b0..b12d74a 100644
--- a/drivers/usb/gadget/u_bam.c
+++ b/drivers/usb/gadget/u_bam.c
@@ -110,7 +110,8 @@
 
 struct gbam_port {
 	unsigned		port_num;
-	spinlock_t		port_lock;
+	spinlock_t		port_lock_ul;
+	spinlock_t		port_lock_dl;
 
 	struct grmnet		*port_usb;
 	struct grmnet		*gr;
@@ -178,9 +179,9 @@
 	struct usb_request		*req;
 	struct usb_ep			*ep;
 
-	spin_lock_irqsave(&port->port_lock, flags);
+	spin_lock_irqsave(&port->port_lock_dl, flags);
 	if (!port->port_usb) {
-		spin_unlock_irqrestore(&port->port_lock, flags);
+		spin_unlock_irqrestore(&port->port_lock_dl, flags);
 		return;
 	}
 
@@ -189,7 +190,7 @@
 	while (!list_empty(&d->tx_idle)) {
 		skb = __skb_dequeue(&d->tx_skb_q);
 		if (!skb) {
-			spin_unlock_irqrestore(&port->port_lock, flags);
+			spin_unlock_irqrestore(&port->port_lock_dl, flags);
 			return;
 		}
 		req = list_first_entry(&d->tx_idle,
@@ -201,9 +202,9 @@
 
 		list_del(&req->list);
 
-		spin_unlock(&port->port_lock);
+		spin_unlock(&port->port_lock_dl);
 		ret = usb_ep_queue(ep, req, GFP_ATOMIC);
-		spin_lock(&port->port_lock);
+		spin_lock(&port->port_lock_dl);
 		if (ret) {
 			pr_err("%s: usb epIn failed\n", __func__);
 			list_add(&req->list, &d->tx_idle);
@@ -212,7 +213,7 @@
 		}
 		d->to_host++;
 	}
-	spin_unlock_irqrestore(&port->port_lock, flags);
+	spin_unlock_irqrestore(&port->port_lock_dl, flags);
 }
 
 void gbam_data_recv_cb(void *p, struct sk_buff *skb)
@@ -227,9 +228,9 @@
 	pr_debug("%s: p:%p#%d d:%p skb_len:%d\n", __func__,
 			port, port->port_num, d, skb->len);
 
-	spin_lock_irqsave(&port->port_lock, flags);
+	spin_lock_irqsave(&port->port_lock_dl, flags);
 	if (!port->port_usb) {
-		spin_unlock_irqrestore(&port->port_lock, flags);
+		spin_unlock_irqrestore(&port->port_lock_dl, flags);
 		dev_kfree_skb_any(skb);
 		return;
 	}
@@ -239,13 +240,13 @@
 		if (printk_ratelimit())
 			pr_err("%s: tx pkt dropped: tx_drop_cnt:%u\n",
 					__func__, d->tohost_drp_cnt);
-		spin_unlock_irqrestore(&port->port_lock, flags);
+		spin_unlock_irqrestore(&port->port_lock_dl, flags);
 		dev_kfree_skb_any(skb);
 		return;
 	}
 
 	__skb_queue_tail(&d->tx_skb_q, skb);
-	spin_unlock_irqrestore(&port->port_lock, flags);
+	spin_unlock_irqrestore(&port->port_lock_dl, flags);
 
 	gbam_write_data_tohost(port);
 }
@@ -261,7 +262,7 @@
 
 	dev_kfree_skb_any(skb);
 
-	spin_lock_irqsave(&port->port_lock, flags);
+	spin_lock_irqsave(&port->port_lock_ul, flags);
 
 	d->pending_with_bam--;
 
@@ -269,7 +270,7 @@
 			port, d, d->to_modem,
 			d->pending_with_bam, port->port_num);
 
-	spin_unlock_irqrestore(&port->port_lock, flags);
+	spin_unlock_irqrestore(&port->port_lock_ul, flags);
 
 	queue_work(gbam_wq, &d->write_tobam_w);
 }
@@ -286,9 +287,9 @@
 	d = container_of(w, struct bam_ch_info, write_tobam_w);
 	port = d->port;
 
-	spin_lock_irqsave(&port->port_lock, flags);
+	spin_lock_irqsave(&port->port_lock_ul, flags);
 	if (!port->port_usb) {
-		spin_unlock_irqrestore(&port->port_lock, flags);
+		spin_unlock_irqrestore(&port->port_lock_ul, flags);
 		return;
 	}
 
@@ -304,9 +305,9 @@
 				port, d, d->to_modem, d->pending_with_bam,
 				port->port_num);
 
-		spin_unlock_irqrestore(&port->port_lock, flags);
+		spin_unlock_irqrestore(&port->port_lock_ul, flags);
 		ret = msm_bam_dmux_write(d->id, skb);
-		spin_lock_irqsave(&port->port_lock, flags);
+		spin_lock_irqsave(&port->port_lock_ul, flags);
 		if (ret) {
 			pr_debug("%s: write error:%d\n", __func__, ret);
 			d->pending_with_bam--;
@@ -319,7 +320,7 @@
 
 	qlen = d->rx_skb_q.qlen;
 
-	spin_unlock_irqrestore(&port->port_lock, flags);
+	spin_unlock_irqrestore(&port->port_lock_ul, flags);
 
 	if (qlen < BAM_MUX_RX_PKT_FCTRL_DIS_TSHOLD)
 		gbam_start_rx(port);
@@ -351,10 +352,10 @@
 	if (!port)
 		return;
 
-	spin_lock(&port->port_lock);
+	spin_lock(&port->port_lock_dl);
 	d = &port->data_ch;
 	list_add_tail(&req->list, &d->tx_idle);
-	spin_unlock(&port->port_lock);
+	spin_unlock(&port->port_lock_dl);
 
 	gbam_write_data_tohost(port);
 }
@@ -389,7 +390,7 @@
 		break;
 	}
 
-	spin_lock(&port->port_lock);
+	spin_lock(&port->port_lock_ul);
 	if (queue) {
 		__skb_queue_tail(&d->rx_skb_q, skb);
 		queue_work(gbam_wq, &d->write_tobam_w);
@@ -402,16 +403,16 @@
 		d->rx_skb_q.qlen >= bam_mux_rx_fctrl_en_thld) {
 
 		list_add_tail(&req->list, &d->rx_idle);
-		spin_unlock(&port->port_lock);
+		spin_unlock(&port->port_lock_ul);
 		return;
 	}
-	spin_unlock(&port->port_lock);
+	spin_unlock(&port->port_lock_ul);
 
 	skb = alloc_skb(bam_mux_rx_req_size + BAM_MUX_HDR, GFP_ATOMIC);
 	if (!skb) {
-		spin_lock(&port->port_lock);
+		spin_lock(&port->port_lock_ul);
 		list_add_tail(&req->list, &d->rx_idle);
-		spin_unlock(&port->port_lock);
+		spin_unlock(&port->port_lock_ul);
 		return;
 	}
 	skb_reserve(skb, BAM_MUX_HDR);
@@ -428,9 +429,9 @@
 			pr_err("%s: data rx enqueue err %d\n",
 					__func__, status);
 
-		spin_lock(&port->port_lock);
+		spin_lock(&port->port_lock_ul);
 		list_add_tail(&req->list, &d->rx_idle);
-		spin_unlock(&port->port_lock);
+		spin_unlock(&port->port_lock_ul);
 	}
 }
 
@@ -457,9 +458,9 @@
 	int				ret;
 	struct sk_buff			*skb;
 
-	spin_lock_irqsave(&port->port_lock, flags);
+	spin_lock_irqsave(&port->port_lock_ul, flags);
 	if (!port->port_usb) {
-		spin_unlock_irqrestore(&port->port_lock, flags);
+		spin_unlock_irqrestore(&port->port_lock_ul, flags);
 		return;
 	}
 
@@ -484,9 +485,9 @@
 		req->length = bam_mux_rx_req_size;
 		req->context = skb;
 
-		spin_unlock_irqrestore(&port->port_lock, flags);
+		spin_unlock_irqrestore(&port->port_lock_ul, flags);
 		ret = usb_ep_queue(ep, req, GFP_ATOMIC);
-		spin_lock_irqsave(&port->port_lock, flags);
+		spin_lock_irqsave(&port->port_lock_ul, flags);
 		if (ret) {
 			dev_kfree_skb_any(skb);
 
@@ -500,7 +501,7 @@
 			break;
 		}
 	}
-	spin_unlock_irqrestore(&port->port_lock, flags);
+	spin_unlock_irqrestore(&port->port_lock_ul, flags);
 }
 
 static void gbam_start_endless_rx(struct gbam_port *port)
@@ -532,9 +533,9 @@
 
 	pr_debug("%s: port:%p\n", __func__, port);
 
-	spin_lock_irqsave(&port->port_lock, flags);
+	spin_lock_irqsave(&port->port_lock_ul, flags);
 	if (!port->port_usb) {
-		spin_unlock_irqrestore(&port->port_lock, flags);
+		spin_unlock_irqrestore(&port->port_lock_ul, flags);
 		return;
 	}
 
@@ -547,6 +548,8 @@
 		return;
 	}
 
+	spin_unlock_irqrestore(&port->port_lock_ul, flags);
+	spin_lock_irqsave(&port->port_lock_dl, flags);
 	ep = port->port_usb->in;
 	ret = gbam_alloc_requests(ep, &d->tx_idle, bam_mux_tx_q_size,
 			gbam_epin_complete, GFP_ATOMIC);
@@ -556,7 +559,7 @@
 		return;
 	}
 
-	spin_unlock_irqrestore(&port->port_lock, flags);
+	spin_unlock_irqrestore(&port->port_lock_dl, flags);
 
 	/* queue out requests */
 	gbam_start_rx(port);
@@ -580,7 +583,8 @@
 	unsigned long		flags;
 	struct bam_ch_info	*d;
 
-	spin_lock_irqsave(&port->port_lock, flags);
+	spin_lock_irqsave(&port->port_lock_ul, flags);
+	spin_lock_irqsave(&port->port_lock_dl, flags);
 
 	if (!port || !port->port_usb)
 		goto free_buf_out;
@@ -597,7 +601,8 @@
 		dev_kfree_skb_any(skb);
 
 free_buf_out:
-	spin_unlock_irqrestore(&port->port_lock, flags);
+	spin_unlock_irqrestore(&port->port_lock_dl, flags);
+	spin_unlock_irqrestore(&port->port_lock_ul, flags);
 }
 
 static void gbam_disconnect_work(struct work_struct *w)
@@ -619,9 +624,11 @@
 			container_of(w, struct gbam_port, disconnect_w);
 	unsigned long		flags;
 
-	spin_lock_irqsave(&port->port_lock, flags);
+	spin_lock_irqsave(&port->port_lock_ul, flags);
+	spin_lock_irqsave(&port->port_lock_dl, flags);
 	port->port_usb = 0;
-	spin_unlock_irqrestore(&port->port_lock, flags);
+	spin_unlock_irqrestore(&port->port_lock_dl, flags);
+	spin_unlock_irqrestore(&port->port_lock_ul, flags);
 
 	/* disable endpoints */
 	usb_ep_disable(port->gr->out);
@@ -636,12 +643,15 @@
 	int ret;
 	unsigned long flags;
 
-	spin_lock_irqsave(&port->port_lock, flags);
+	spin_lock_irqsave(&port->port_lock_ul, flags);
+	spin_lock_irqsave(&port->port_lock_dl, flags);
 	if (!port->port_usb) {
-		spin_unlock_irqrestore(&port->port_lock, flags);
+		spin_unlock_irqrestore(&port->port_lock_dl, flags);
+		spin_unlock_irqrestore(&port->port_lock_ul, flags);
 		return;
 	}
-	spin_unlock_irqrestore(&port->port_lock, flags);
+	spin_unlock_irqrestore(&port->port_lock_dl, flags);
+	spin_unlock_irqrestore(&port->port_lock_ul, flags);
 
 	if (!test_bit(BAM_CH_READY, &d->flags))
 		return;
@@ -683,9 +693,11 @@
 		return;
 	}
 	port->gr->out->driver_data = port;
-	spin_lock_irqsave(&port->port_lock, flags);
+	spin_lock_irqsave(&port->port_lock_ul, flags);
+	spin_lock_irqsave(&port->port_lock_dl, flags);
 	port->port_usb = port->gr;
-	spin_unlock_irqrestore(&port->port_lock, flags);
+	spin_unlock_irqrestore(&port->port_lock_dl, flags);
+	spin_unlock_irqrestore(&port->port_lock_ul, flags);
 
 	ret = usb_bam_connect(d->connection_idx, &d->src_pipe_idx,
 						  &d->dst_pipe_idx);
@@ -742,10 +754,12 @@
 			set_bit(BAM_CH_READY, &d->flags);
 
 			/* if usb is online, try opening bam_ch */
-			spin_lock_irqsave(&port->port_lock, flags);
+			spin_lock_irqsave(&port->port_lock_ul, flags);
+			spin_lock_irqsave(&port->port_lock_dl, flags);
 			if (port->port_usb)
 				queue_work(gbam_wq, &port->connect_w);
-			spin_unlock_irqrestore(&port->port_lock, flags);
+			spin_unlock_irqrestore(&port->port_lock_dl, flags);
+			spin_unlock_irqrestore(&port->port_lock_ul, flags);
 
 			break;
 		}
@@ -772,12 +786,14 @@
 			port = bam_ports[i].port;
 			d = &port->data_ch;
 
-			spin_lock_irqsave(&port->port_lock, flags);
+			spin_lock_irqsave(&port->port_lock_ul, flags);
+			spin_lock_irqsave(&port->port_lock_dl, flags);
 			if (port->port_usb) {
 				ep_in = port->port_usb->in;
 				ep_out = port->port_usb->out;
 			}
-			spin_unlock_irqrestore(&port->port_lock, flags);
+			spin_unlock_irqrestore(&port->port_lock_dl, flags);
+			spin_unlock_irqrestore(&port->port_lock_ul, flags);
 
 			if (ep_in)
 				usb_ep_fifo_flush(ep_in);
@@ -827,7 +843,8 @@
 	port->port_num = portno;
 
 	/* port initialization */
-	spin_lock_init(&port->port_lock);
+	spin_lock_init(&port->port_lock_ul);
+	spin_lock_init(&port->port_lock_dl);
 	INIT_WORK(&port->connect_w, gbam_connect_work);
 	INIT_WORK(&port->disconnect_w, gbam_disconnect_work);
 
@@ -867,7 +884,8 @@
 	port->port_num = portno;
 
 	/* port initialization */
-	spin_lock_init(&port->port_lock);
+	spin_lock_init(&port->port_lock_ul);
+	spin_lock_init(&port->port_lock_dl);
 
 	INIT_WORK(&port->connect_w, gbam2bam_connect_work);
 	INIT_WORK(&port->disconnect_w, gbam2bam_disconnect_work);
@@ -903,7 +921,8 @@
 		port = bam_ports[i].port;
 		if (!port)
 			continue;
-		spin_lock_irqsave(&port->port_lock, flags);
+		spin_lock_irqsave(&port->port_lock_ul, flags);
+		spin_lock_irqsave(&port->port_lock_dl, flags);
 
 		d = &port->data_ch;
 
@@ -926,7 +945,8 @@
 				test_bit(BAM_CH_OPENED, &d->flags),
 				test_bit(BAM_CH_READY, &d->flags));
 
-		spin_unlock_irqrestore(&port->port_lock, flags);
+		spin_unlock_irqrestore(&port->port_lock_dl, flags);
+		spin_unlock_irqrestore(&port->port_lock_ul, flags);
 	}
 
 	ret = simple_read_from_buffer(ubuf, count, ppos, buf, temp);
@@ -949,7 +969,8 @@
 		if (!port)
 			continue;
 
-		spin_lock_irqsave(&port->port_lock, flags);
+		spin_lock_irqsave(&port->port_lock_ul, flags);
+		spin_lock_irqsave(&port->port_lock_dl, flags);
 
 		d = &port->data_ch;
 
@@ -959,7 +980,8 @@
 		d->tohost_drp_cnt = 0;
 		d->tomodem_drp_cnt = 0;
 
-		spin_unlock_irqrestore(&port->port_lock, flags);
+		spin_unlock_irqrestore(&port->port_lock_dl, flags);
+		spin_unlock_irqrestore(&port->port_lock_ul, flags);
 	}
 	return count;
 }
@@ -1024,9 +1046,11 @@
 	if (trans == USB_GADGET_XPORT_BAM) {
 		gbam_free_buffers(port);
 
-		spin_lock_irqsave(&port->port_lock, flags);
-		port->port_usb = 0;
-		spin_unlock_irqrestore(&port->port_lock, flags);
+	spin_lock_irqsave(&port->port_lock_ul, flags);
+	spin_lock_irqsave(&port->port_lock_dl, flags);
+	port->port_usb = 0;
+	spin_unlock_irqrestore(&port->port_lock_dl, flags);
+	spin_unlock_irqrestore(&port->port_lock_ul, flags);
 
 		/* disable endpoints */
 		usb_ep_disable(gr->out);
@@ -1086,15 +1110,17 @@
 		}
 		gr->out->driver_data = port;
 
-		spin_lock_irqsave(&port->port_lock, flags);
-		port->port_usb = gr;
+	spin_lock_irqsave(&port->port_lock_ul, flags);
+	spin_lock_irqsave(&port->port_lock_dl, flags);
+	port->port_usb = gr;
 
 		d->to_host = 0;
 		d->to_modem = 0;
 		d->pending_with_bam = 0;
 		d->tohost_drp_cnt = 0;
 		d->tomodem_drp_cnt = 0;
-		spin_unlock_irqrestore(&port->port_lock, flags);
+	spin_unlock_irqrestore(&port->port_lock_dl, flags);
+	spin_unlock_irqrestore(&port->port_lock_ul, flags);
 	}
 
 	if (trans == USB_GADGET_XPORT_BAM2BAM) {