Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1329579 > unrolled thread

[RFC][PATCH v2] usb: gadget: u_ether: Fix data stall issue in RNDIS tethering mode

Started byAmit Pundir <amit.pundir@linaro.org>
First post2016-02-08 22:20 +0100
Last post2016-02-08 22:20 +0100
Articles 1 — 1 participant

Back to article view | Back to linux.kernel


Contents

  [RFC][PATCH v2] usb: gadget: u_ether: Fix data stall issue in RNDIS tethering mode Amit Pundir <amit.pundir@linaro.org> - 2016-02-08 22:20 +0100

#1329579 — [RFC][PATCH v2] usb: gadget: u_ether: Fix data stall issue in RNDIS tethering mode

FromAmit Pundir <amit.pundir@linaro.org>
Date2016-02-08 22:20 +0100
Subject[RFC][PATCH v2] usb: gadget: u_ether: Fix data stall issue in RNDIS tethering mode
Message-ID<r01nY-2ow-19@gated-at.bofh.it>
From: Badhri Jagan Sridharan <Badhri@google.com>

For dual speed gadget, with current no. of request(10), there is
possibility of corner case occurrence where all 10 requests are queued
to HW without setting IOC bit, which could lead to data stall in
RNDIS tethering and RNDIS local networking.

With this patch, counter will be incremented before queueing request to
HW and sets IOC bit for every nth request due to which the corner case
of all requests queued to HW without IOC bit set will be avoided.

Cc: Felipe Balbi <balbi@kernel.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Mike Looijmans <mike.looijmans@topic.nl> 
Cc: Robert Baldyga <r.baldyga@samsung.com>
Cc: Android Kernel Team <kernel-team@android.com>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Sumit Semwal <sumit.semwal@linaro.org>
Cc: Praneeth Bajjuri <praneeth@ti.com>
Signed-off-by: Vijayavardhan Vennapusa <vvreddy@codeaurora.org>
[pundir:
 * cherry-picked this patch from AOSP experimental/android-4.4 tree.
 * folded in an AOSP build fix from Praneeth Bajjuri <praneeth@ti.com>]
Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
---
v2: folded in the build fix for v1 from AOSP. Updated the commit log.

v1: Cherry-picked this patch from AOSP common/experimental/android-4.4 tree.
    I could not find upstream submission history for this patch, so my
    apologies in advance if this has already been NACKed before.

 drivers/usb/gadget/function/u_ether.c | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c
index 9a69332..7f98a2d 100644
--- a/drivers/usb/gadget/function/u_ether.c
+++ b/drivers/usb/gadget/function/u_ether.c
@@ -64,7 +64,7 @@ struct eth_dev {
 
 	spinlock_t		req_lock;	/* guard {rx,tx}_reqs */
 	struct list_head	tx_reqs, rx_reqs;
-	atomic_t		tx_qlen;
+	unsigned		tx_qlen;
 
 	struct sk_buff_head	rx_frames;
 
@@ -464,7 +464,6 @@ static void tx_complete(struct usb_ep *ep, struct usb_request *req)
 	spin_unlock(&dev->req_lock);
 	dev_kfree_skb_any(skb);
 
-	atomic_dec(&dev->tx_qlen);
 	if (netif_carrier_ok(dev->net))
 		netif_wake_queue(dev->net);
 }
@@ -584,12 +583,19 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb,
 
 	req->length = length;
 
-	/* throttle high/super speed IRQ rate back slightly */
-	if (gadget_is_dualspeed(dev->gadget))
-		req->no_interrupt = (dev->gadget->speed == USB_SPEED_HIGH ||
-				     dev->gadget->speed == USB_SPEED_SUPER)
-			? ((atomic_read(&dev->tx_qlen) % dev->qmult) != 0)
-			: 0;
+	/* throttle highspeed IRQ rate back slightly */
+	if (gadget_is_dualspeed(dev->gadget) &&
+			 (dev->gadget->speed == USB_SPEED_HIGH)) {
+		dev->tx_qlen++;
+		if (dev->tx_qlen == dev->qmult) {
+			req->no_interrupt = 0;
+			dev->tx_qlen = 0;
+		} else {
+			req->no_interrupt = 1;
+		}
+	} else {
+		req->no_interrupt = 0;
+	}
 
 	retval = usb_ep_queue(in, req, GFP_ATOMIC);
 	switch (retval) {
@@ -598,7 +604,6 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb,
 		break;
 	case 0:
 		net->trans_start = jiffies;
-		atomic_inc(&dev->tx_qlen);
 	}
 
 	if (retval) {
@@ -625,7 +630,7 @@ static void eth_start(struct eth_dev *dev, gfp_t gfp_flags)
 	rx_fill(dev, gfp_flags);
 
 	/* and open the tx floodgates */
-	atomic_set(&dev->tx_qlen, 0);
+	dev->tx_qlen = 0;
 	netif_wake_queue(dev->net);
 }
 
-- 
1.9.1

[toc] | [standalone]


Back to top | Article view | linux.kernel


csiph-web