linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net 0/3] r8152 bug fixes
@ 2013-10-29  7:56 Hayes Wang
  2013-10-29  7:56 ` [PATCH net 1/3] r8152: fix tx/rx memory overflow Hayes Wang
                   ` (3 more replies)
  0 siblings, 4 replies; 15+ messages in thread
From: Hayes Wang @ 2013-10-29  7:56 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

These could fix some driver issues.

Hayes Wang (3):
  r8152: fix tx/rx memory overflow
  r8152: modify the tx flow
  r8152: fix incorrect type in assignment

 drivers/net/usb/r8152.c | 100 +++++++++++++++++-------------------------------
 1 file changed, 36 insertions(+), 64 deletions(-)

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH net 1/3] r8152: fix tx/rx memory overflow
  2013-10-29  7:56 [PATCH net 0/3] r8152 bug fixes Hayes Wang
@ 2013-10-29  7:56 ` Hayes Wang
  2013-10-29  7:56 ` [PATCH net 2/3] r8152: modify the tx flow Hayes Wang
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 15+ messages in thread
From: Hayes Wang @ 2013-10-29  7:56 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

The tx/rx would access the memory which is out of the desired range.
Modify the method of checking the end of the memory to avoid it.

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 drivers/net/usb/r8152.c | 30 +++++++++++++++++-------------
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index f3fce41..5dbfe50 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -24,7 +24,7 @@
 #include <linux/ipv6.h>
 
 /* Version Information */
-#define DRIVER_VERSION "v1.01.0 (2013/08/12)"
+#define DRIVER_VERSION "v1.02.0 (2013/10/28)"
 #define DRIVER_AUTHOR "Realtek linux nic maintainers <nic_swsd@realtek.com>"
 #define DRIVER_DESC "Realtek RTL8152 Based USB 2.0 Ethernet Adapters"
 #define MODULENAME "r8152"
@@ -1136,14 +1136,14 @@ r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, struct sk_buff *skb)
 
 static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 {
-	u32 remain;
+	int remain;
 	u8 *tx_data;
 
 	tx_data = agg->head;
 	agg->skb_num = agg->skb_len = 0;
-	remain = rx_buf_sz - sizeof(struct tx_desc);
+	remain = rx_buf_sz;
 
-	while (remain >= ETH_ZLEN) {
+	while (remain >= ETH_ZLEN + sizeof(struct tx_desc)) {
 		struct tx_desc *tx_desc;
 		struct sk_buff *skb;
 		unsigned int len;
@@ -1152,12 +1152,14 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 		if (!skb)
 			break;
 
+		remain -= sizeof(*tx_desc);
 		len = skb->len;
 		if (remain < len) {
 			skb_queue_head(&tp->tx_queue, skb);
 			break;
 		}
 
+		tx_data = tx_agg_align(tx_data);
 		tx_desc = (struct tx_desc *)tx_data;
 		tx_data += sizeof(*tx_desc);
 
@@ -1167,9 +1169,8 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 		agg->skb_len += len;
 		dev_kfree_skb_any(skb);
 
-		tx_data = tx_agg_align(tx_data + len);
-		remain = rx_buf_sz - sizeof(*tx_desc) -
-			 (u32)((void *)tx_data - agg->head);
+		tx_data += len;
+		remain = rx_buf_sz - (int)(tx_agg_align(tx_data) - agg->head);
 	}
 
 	usb_fill_bulk_urb(agg->urb, tp->udev, usb_sndbulkpipe(tp->udev, 2),
@@ -1188,7 +1189,6 @@ static void rx_bottom(struct r8152 *tp)
 	list_for_each_safe(cursor, next, &tp->rx_done) {
 		struct rx_desc *rx_desc;
 		struct rx_agg *agg;
-		unsigned pkt_len;
 		int len_used = 0;
 		struct urb *urb;
 		u8 *rx_data;
@@ -1204,17 +1204,22 @@ static void rx_bottom(struct r8152 *tp)
 
 		rx_desc = agg->head;
 		rx_data = agg->head;
-		pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK;
-		len_used += sizeof(struct rx_desc) + pkt_len;
+		len_used += sizeof(struct rx_desc);
 
-		while (urb->actual_length >= len_used) {
+		while (urb->actual_length > len_used) {
 			struct net_device *netdev = tp->netdev;
 			struct net_device_stats *stats;
+			unsigned pkt_len;
 			struct sk_buff *skb;
 
+			pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK;
 			if (pkt_len < ETH_ZLEN)
 				break;
 
+			len_used += pkt_len;
+			if (urb->actual_length < len_used)
+				break;
+
 			stats = rtl8152_get_stats(netdev);
 
 			pkt_len -= 4; /* CRC */
@@ -1234,9 +1239,8 @@ static void rx_bottom(struct r8152 *tp)
 
 			rx_data = rx_agg_align(rx_data + pkt_len + 4);
 			rx_desc = (struct rx_desc *)rx_data;
-			pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK;
 			len_used = (int)(rx_data - (u8 *)agg->head);
-			len_used += sizeof(struct rx_desc) + pkt_len;
+			len_used += sizeof(struct rx_desc);
 		}
 
 submit:
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH net 2/3] r8152: modify the tx flow
  2013-10-29  7:56 [PATCH net 0/3] r8152 bug fixes Hayes Wang
  2013-10-29  7:56 ` [PATCH net 1/3] r8152: fix tx/rx memory overflow Hayes Wang
@ 2013-10-29  7:56 ` Hayes Wang
  2013-10-29 21:49   ` David Miller
  2013-10-29  7:56 ` [PATCH net 3/3] r8152: fix incorrect type in assignment Hayes Wang
  2013-10-30  7:13 ` [PATCH net v2 0/3] r8152 bug fixes Hayes Wang
  3 siblings, 1 reply; 15+ messages in thread
From: Hayes Wang @ 2013-10-29  7:56 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Let rtl8152_start_xmit() to queue packet only, and tx_bottom() would
send all of the packets. This simplify the code and make sure all the
packet would be sent by the original order.

Support stopping and waking tx queue. The maximum tx queue length
is 60.

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 drivers/net/usb/r8152.c | 52 ++++++++++---------------------------------------
 1 file changed, 10 insertions(+), 42 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 5dbfe50..1647931 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -276,6 +276,8 @@ enum rtl_register_content {
 
 #define INTR_LINK		0x0004
 
+#define TX_QLEN			60
+
 #define RTL8152_REQT_READ	0xc0
 #define RTL8152_REQT_WRITE	0x40
 #define RTL8152_REQ_GET_REGS	0x05
@@ -1173,6 +1175,9 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 		remain = rx_buf_sz - (int)(tx_agg_align(tx_data) - agg->head);
 	}
 
+	if (netif_queue_stopped(tp->netdev))
+		netif_wake_queue(tp->netdev);
+
 	usb_fill_bulk_urb(agg->urb, tp->udev, usb_sndbulkpipe(tp->udev, 2),
 			  agg->head, (int)(tx_data - (u8 *)agg->head),
 			  (usb_complete_t)write_bulk_callback, agg);
@@ -1388,53 +1393,16 @@ static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb,
 					    struct net_device *netdev)
 {
 	struct r8152 *tp = netdev_priv(netdev);
-	struct net_device_stats *stats = rtl8152_get_stats(netdev);
-	unsigned long flags;
-	struct tx_agg *agg = NULL;
-	struct tx_desc *tx_desc;
-	unsigned int len;
-	u8 *tx_data;
-	int res;
 
 	skb_tx_timestamp(skb);
 
-	/* If tx_queue is not empty, it means at least one previous packt */
-	/* is waiting for sending. Don't send current one before it.      */
-	if (skb_queue_empty(&tp->tx_queue))
-		agg = r8152_get_tx_agg(tp);
-
-	if (!agg) {
-		skb_queue_tail(&tp->tx_queue, skb);
-		return NETDEV_TX_OK;
-	}
+	skb_queue_tail(&tp->tx_queue, skb);
 
-	tx_desc = (struct tx_desc *)agg->head;
-	tx_data = agg->head + sizeof(*tx_desc);
-	agg->skb_num = agg->skb_len = 0;
+	if (skb_queue_len(&tp->tx_queue) > TX_QLEN)
+		netif_stop_queue(netdev);
 
-	len = skb->len;
-	r8152_tx_csum(tp, tx_desc, skb);
-	memcpy(tx_data, skb->data, len);
-	dev_kfree_skb_any(skb);
-	agg->skb_num++;
-	agg->skb_len += len;
-	usb_fill_bulk_urb(agg->urb, tp->udev, usb_sndbulkpipe(tp->udev, 2),
-			  agg->head, len + sizeof(*tx_desc),
-			  (usb_complete_t)write_bulk_callback, agg);
-	res = usb_submit_urb(agg->urb, GFP_ATOMIC);
-	if (res) {
-		/* Can we get/handle EPIPE here? */
-		if (res == -ENODEV) {
-			netif_device_detach(tp->netdev);
-		} else {
-			netif_warn(tp, tx_err, netdev,
-				   "failed tx_urb %d\n", res);
-			stats->tx_dropped++;
-			spin_lock_irqsave(&tp->tx_lock, flags);
-			list_add_tail(&agg->list, &tp->tx_free);
-			spin_unlock_irqrestore(&tp->tx_lock, flags);
-		}
-	}
+	if (!list_empty(&tp->tx_free))
+		tasklet_schedule(&tp->tl);
 
 	return NETDEV_TX_OK;
 }
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH net 3/3] r8152: fix incorrect type in assignment
  2013-10-29  7:56 [PATCH net 0/3] r8152 bug fixes Hayes Wang
  2013-10-29  7:56 ` [PATCH net 1/3] r8152: fix tx/rx memory overflow Hayes Wang
  2013-10-29  7:56 ` [PATCH net 2/3] r8152: modify the tx flow Hayes Wang
@ 2013-10-29  7:56 ` Hayes Wang
  2013-10-30  7:13 ` [PATCH net v2 0/3] r8152 bug fixes Hayes Wang
  3 siblings, 0 replies; 15+ messages in thread
From: Hayes Wang @ 2013-10-29  7:56 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Correct some declaration.

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 drivers/net/usb/r8152.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 1647931..b92b7f4 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -309,22 +309,22 @@ enum rtl8152_flags {
 #define MCU_TYPE_USB			0x0000
 
 struct rx_desc {
-	u32 opts1;
+	__le32 opts1;
 #define RX_LEN_MASK			0x7fff
-	u32 opts2;
-	u32 opts3;
-	u32 opts4;
-	u32 opts5;
-	u32 opts6;
+	__le32 opts2;
+	__le32 opts3;
+	__le32 opts4;
+	__le32 opts5;
+	__le32 opts6;
 };
 
 struct tx_desc {
-	u32 opts1;
+	__le32 opts1;
 #define TX_FS			(1 << 31) /* First segment of a packet */
 #define TX_LS			(1 << 30) /* Final segment of a packet */
 #define TX_LEN_MASK		0x3ffff
 
-	u32 opts2;
+	__le32 opts2;
 #define UDP_CS			(1 << 31) /* Calculate UDP/IP checksum */
 #define TCP_CS			(1 << 30) /* Calculate TCP/IP checksum */
 #define IPV4_CS			(1 << 29) /* Calculate IPv4 checksum */
@@ -878,7 +878,7 @@ static void write_bulk_callback(struct urb *urb)
 static void intr_callback(struct urb *urb)
 {
 	struct r8152 *tp;
-	__u16 *d;
+	__le16 *d;
 	int status = urb->status;
 	int res;
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH net 2/3] r8152: modify the tx flow
  2013-10-29  7:56 ` [PATCH net 2/3] r8152: modify the tx flow Hayes Wang
@ 2013-10-29 21:49   ` David Miller
  2013-10-30  3:03     ` hayeswang
  0 siblings, 1 reply; 15+ messages in thread
From: David Miller @ 2013-10-29 21:49 UTC (permalink / raw)
  To: hayeswang; +Cc: netdev, nic_swsd, linux-kernel, linux-usb

From: Hayes Wang <hayeswang@realtek.com>
Date: Tue, 29 Oct 2013 15:56:16 +0800

> Support stopping and waking tx queue. The maximum tx queue length
> is 60.

What is so special about the number 60?  It seems arbitrary, and if
it isn't arbitrary you haven't described why this value was choosen.

I've asked you politely last time around to significantly improve
the quality of your commit messages, and you haven't done this at
all.

I'm not applying any of these patches until your commit messages
properly describe your changes completely.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: [PATCH net 2/3] r8152: modify the tx flow
  2013-10-29 21:49   ` David Miller
@ 2013-10-30  3:03     ` hayeswang
  2013-10-30  3:08       ` David Miller
  0 siblings, 1 reply; 15+ messages in thread
From: hayeswang @ 2013-10-30  3:03 UTC (permalink / raw)
  To: 'David Miller'
  Cc: netdev, 'nic_swsd', linux-kernel, linux-usb

 David Miller [mailto:davem@davemloft.net] 
> Sent: Wednesday, October 30, 2013 5:50 AM
> To: Hayeswang
> Cc: netdev@vger.kernel.org; nic_swsd; 
> linux-kernel@vger.kernel.org; linux-usb@vger.kernel.org
> Subject: Re: [PATCH net 2/3] r8152: modify the tx flow
> 
> From: Hayes Wang <hayeswang@realtek.com>
> Date: Tue, 29 Oct 2013 15:56:16 +0800
> 
> > Support stopping and waking tx queue. The maximum tx queue length
> > is 60.
> 
> What is so special about the number 60?  It seems arbitrary, and if
> it isn't arbitrary you haven't described why this value was choosen.

The value is arbitrary. I think it is better to stop tx when
queuing many packets, otherwise all the available memory may
be used for tx skb. The queue length could be any value or
unlimited if the memory is enough. Should I remove it?

> I've asked you politely last time around to significantly improve
> the quality of your commit messages, and you haven't done this at
> all.

I thought you indicated the last patch only and the others are clear enough.
I would improve them.

> I'm not applying any of these patches until your commit messages
> properly describe your changes completely.
> 


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net 2/3] r8152: modify the tx flow
  2013-10-30  3:03     ` hayeswang
@ 2013-10-30  3:08       ` David Miller
  0 siblings, 0 replies; 15+ messages in thread
From: David Miller @ 2013-10-30  3:08 UTC (permalink / raw)
  To: hayeswang; +Cc: netdev, nic_swsd, linux-kernel, linux-usb

From: hayeswang <hayeswang@realtek.com>
Date: Wed, 30 Oct 2013 11:03:55 +0800

>  David Miller [mailto:davem@davemloft.net] 
>> Sent: Wednesday, October 30, 2013 5:50 AM
>> To: Hayeswang
>> Cc: netdev@vger.kernel.org; nic_swsd; 
>> linux-kernel@vger.kernel.org; linux-usb@vger.kernel.org
>> Subject: Re: [PATCH net 2/3] r8152: modify the tx flow
>> 
>> From: Hayes Wang <hayeswang@realtek.com>
>> Date: Tue, 29 Oct 2013 15:56:16 +0800
>> 
>> > Support stopping and waking tx queue. The maximum tx queue length
>> > is 60.
>> 
>> What is so special about the number 60?  It seems arbitrary, and if
>> it isn't arbitrary you haven't described why this value was choosen.
> 
> The value is arbitrary. I think it is better to stop tx when
> queuing many packets, otherwise all the available memory may
> be used for tx skb. The queue length could be any value or
> unlimited if the memory is enough. Should I remove it?

You should at least pick some value that you have analyzed in some
way.  We've done a lot of work to strongly limit the amount of SKB
data which sits in device queues on transmit, and what you're doing
here works against to those goals.

Ideally you should pick a value which is sufficient to meet two
goals at the same time:

1) With constant transmit traffic coming from the networking stack,
   the device never starves for new transmit data to send.

2) We never queue up more traffic than we need to satisfy requirement
   #1.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH net v2 0/3] r8152 bug fixes
  2013-10-29  7:56 [PATCH net 0/3] r8152 bug fixes Hayes Wang
                   ` (2 preceding siblings ...)
  2013-10-29  7:56 ` [PATCH net 3/3] r8152: fix incorrect type in assignment Hayes Wang
@ 2013-10-30  7:13 ` Hayes Wang
  2013-10-30  7:13   ` [PATCH net v2 1/3] r8152: fix tx/rx memory overflow Hayes Wang
                     ` (2 more replies)
  3 siblings, 3 replies; 15+ messages in thread
From: Hayes Wang @ 2013-10-30  7:13 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

I have update the commit messages. I hope they are clear enough.

I remove the stop/wake tx queue from the second patch first, until
I find a way to determine which value is suitable for TX_QLEN.

Hayes Wang (3):
  r8152: fix tx/rx memory overflow
  r8152: modify the tx flow
  r8152: fix incorrect type in assignment

 drivers/net/usb/r8152.c | 94 +++++++++++++++----------------------------------
 1 file changed, 29 insertions(+), 65 deletions(-)

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH net v2 1/3] r8152: fix tx/rx memory overflow
  2013-10-30  7:13 ` [PATCH net v2 0/3] r8152 bug fixes Hayes Wang
@ 2013-10-30  7:13   ` Hayes Wang
  2013-10-30  7:13   ` [PATCH net v2 2/3] r8152: modify the tx flow Hayes Wang
  2013-10-30  7:13   ` [PATCH net v2 3/3] r8152: fix incorrect type in assignment Hayes Wang
  2 siblings, 0 replies; 15+ messages in thread
From: Hayes Wang @ 2013-10-30  7:13 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

The tx/rx would access the memory which is out of the desired range.
Modify the method of checking the end of the memory to avoid it.

For r8152_tx_agg_fill(), the variable remain may become negative.
However, the declaration is unsigned, so the while loop wouldn't
break when reach the end of the desied memory. Although change the
declaration from unsigned to signed is enough to fix it, I also
modify the checking method for safe. Replace

		remain = rx_buf_sz - sizeof(*tx_desc) -
			 (u32)((void *)tx_data - agg->head);

with

		remain = rx_buf_sz - (int)(tx_agg_align(tx_data) - agg->head);

to make sure the variable remain is always positive. Then, the
overflow wouldn't happen.

For rx_bottom(), the rx_desc should not be used to calculate the
packet length before making sure the rx_desc is in the desired range.
Change the checking to two parts. First, check the descriptor is in
the memory. The other, using the descriptor to find out the packet
length and check if the packet is in the memory.

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 drivers/net/usb/r8152.c | 30 +++++++++++++++++-------------
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index f3fce41..5dbfe50 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -24,7 +24,7 @@
 #include <linux/ipv6.h>
 
 /* Version Information */
-#define DRIVER_VERSION "v1.01.0 (2013/08/12)"
+#define DRIVER_VERSION "v1.02.0 (2013/10/28)"
 #define DRIVER_AUTHOR "Realtek linux nic maintainers <nic_swsd@realtek.com>"
 #define DRIVER_DESC "Realtek RTL8152 Based USB 2.0 Ethernet Adapters"
 #define MODULENAME "r8152"
@@ -1136,14 +1136,14 @@ r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, struct sk_buff *skb)
 
 static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 {
-	u32 remain;
+	int remain;
 	u8 *tx_data;
 
 	tx_data = agg->head;
 	agg->skb_num = agg->skb_len = 0;
-	remain = rx_buf_sz - sizeof(struct tx_desc);
+	remain = rx_buf_sz;
 
-	while (remain >= ETH_ZLEN) {
+	while (remain >= ETH_ZLEN + sizeof(struct tx_desc)) {
 		struct tx_desc *tx_desc;
 		struct sk_buff *skb;
 		unsigned int len;
@@ -1152,12 +1152,14 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 		if (!skb)
 			break;
 
+		remain -= sizeof(*tx_desc);
 		len = skb->len;
 		if (remain < len) {
 			skb_queue_head(&tp->tx_queue, skb);
 			break;
 		}
 
+		tx_data = tx_agg_align(tx_data);
 		tx_desc = (struct tx_desc *)tx_data;
 		tx_data += sizeof(*tx_desc);
 
@@ -1167,9 +1169,8 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 		agg->skb_len += len;
 		dev_kfree_skb_any(skb);
 
-		tx_data = tx_agg_align(tx_data + len);
-		remain = rx_buf_sz - sizeof(*tx_desc) -
-			 (u32)((void *)tx_data - agg->head);
+		tx_data += len;
+		remain = rx_buf_sz - (int)(tx_agg_align(tx_data) - agg->head);
 	}
 
 	usb_fill_bulk_urb(agg->urb, tp->udev, usb_sndbulkpipe(tp->udev, 2),
@@ -1188,7 +1189,6 @@ static void rx_bottom(struct r8152 *tp)
 	list_for_each_safe(cursor, next, &tp->rx_done) {
 		struct rx_desc *rx_desc;
 		struct rx_agg *agg;
-		unsigned pkt_len;
 		int len_used = 0;
 		struct urb *urb;
 		u8 *rx_data;
@@ -1204,17 +1204,22 @@ static void rx_bottom(struct r8152 *tp)
 
 		rx_desc = agg->head;
 		rx_data = agg->head;
-		pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK;
-		len_used += sizeof(struct rx_desc) + pkt_len;
+		len_used += sizeof(struct rx_desc);
 
-		while (urb->actual_length >= len_used) {
+		while (urb->actual_length > len_used) {
 			struct net_device *netdev = tp->netdev;
 			struct net_device_stats *stats;
+			unsigned pkt_len;
 			struct sk_buff *skb;
 
+			pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK;
 			if (pkt_len < ETH_ZLEN)
 				break;
 
+			len_used += pkt_len;
+			if (urb->actual_length < len_used)
+				break;
+
 			stats = rtl8152_get_stats(netdev);
 
 			pkt_len -= 4; /* CRC */
@@ -1234,9 +1239,8 @@ static void rx_bottom(struct r8152 *tp)
 
 			rx_data = rx_agg_align(rx_data + pkt_len + 4);
 			rx_desc = (struct rx_desc *)rx_data;
-			pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK;
 			len_used = (int)(rx_data - (u8 *)agg->head);
-			len_used += sizeof(struct rx_desc) + pkt_len;
+			len_used += sizeof(struct rx_desc);
 		}
 
 submit:
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH net v2 2/3] r8152: modify the tx flow
  2013-10-30  7:13 ` [PATCH net v2 0/3] r8152 bug fixes Hayes Wang
  2013-10-30  7:13   ` [PATCH net v2 1/3] r8152: fix tx/rx memory overflow Hayes Wang
@ 2013-10-30  7:13   ` Hayes Wang
  2013-10-30 21:04     ` David Miller
  2013-10-30  7:13   ` [PATCH net v2 3/3] r8152: fix incorrect type in assignment Hayes Wang
  2 siblings, 1 reply; 15+ messages in thread
From: Hayes Wang @ 2013-10-30  7:13 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Remove the code for sending the packet in the rtl8152_start_xmit().
Let rtl8152_start_xmit() to queue the packet only, and schedule a
tasklet to send the queued packets. This simplify the code and make
sure all the packet would be sent by the original order.

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 drivers/net/usb/r8152.c | 46 +++-------------------------------------------
 1 file changed, 3 insertions(+), 43 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 5dbfe50..763234d 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1388,53 +1388,13 @@ static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb,
 					    struct net_device *netdev)
 {
 	struct r8152 *tp = netdev_priv(netdev);
-	struct net_device_stats *stats = rtl8152_get_stats(netdev);
-	unsigned long flags;
-	struct tx_agg *agg = NULL;
-	struct tx_desc *tx_desc;
-	unsigned int len;
-	u8 *tx_data;
-	int res;
 
 	skb_tx_timestamp(skb);
 
-	/* If tx_queue is not empty, it means at least one previous packt */
-	/* is waiting for sending. Don't send current one before it.      */
-	if (skb_queue_empty(&tp->tx_queue))
-		agg = r8152_get_tx_agg(tp);
-
-	if (!agg) {
-		skb_queue_tail(&tp->tx_queue, skb);
-		return NETDEV_TX_OK;
-	}
-
-	tx_desc = (struct tx_desc *)agg->head;
-	tx_data = agg->head + sizeof(*tx_desc);
-	agg->skb_num = agg->skb_len = 0;
+	skb_queue_tail(&tp->tx_queue, skb);
 
-	len = skb->len;
-	r8152_tx_csum(tp, tx_desc, skb);
-	memcpy(tx_data, skb->data, len);
-	dev_kfree_skb_any(skb);
-	agg->skb_num++;
-	agg->skb_len += len;
-	usb_fill_bulk_urb(agg->urb, tp->udev, usb_sndbulkpipe(tp->udev, 2),
-			  agg->head, len + sizeof(*tx_desc),
-			  (usb_complete_t)write_bulk_callback, agg);
-	res = usb_submit_urb(agg->urb, GFP_ATOMIC);
-	if (res) {
-		/* Can we get/handle EPIPE here? */
-		if (res == -ENODEV) {
-			netif_device_detach(tp->netdev);
-		} else {
-			netif_warn(tp, tx_err, netdev,
-				   "failed tx_urb %d\n", res);
-			stats->tx_dropped++;
-			spin_lock_irqsave(&tp->tx_lock, flags);
-			list_add_tail(&agg->list, &tp->tx_free);
-			spin_unlock_irqrestore(&tp->tx_lock, flags);
-		}
-	}
+	if (!list_empty(&tp->tx_free))
+		tasklet_schedule(&tp->tl);
 
 	return NETDEV_TX_OK;
 }
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH net v2 3/3] r8152: fix incorrect type in assignment
  2013-10-30  7:13 ` [PATCH net v2 0/3] r8152 bug fixes Hayes Wang
  2013-10-30  7:13   ` [PATCH net v2 1/3] r8152: fix tx/rx memory overflow Hayes Wang
  2013-10-30  7:13   ` [PATCH net v2 2/3] r8152: modify the tx flow Hayes Wang
@ 2013-10-30  7:13   ` Hayes Wang
  2 siblings, 0 replies; 15+ messages in thread
From: Hayes Wang @ 2013-10-30  7:13 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

The data from the hardware should be little endian. Correct the
declaration.

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 drivers/net/usb/r8152.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 763234d..a77bdb8 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -307,22 +307,22 @@ enum rtl8152_flags {
 #define MCU_TYPE_USB			0x0000
 
 struct rx_desc {
-	u32 opts1;
+	__le32 opts1;
 #define RX_LEN_MASK			0x7fff
-	u32 opts2;
-	u32 opts3;
-	u32 opts4;
-	u32 opts5;
-	u32 opts6;
+	__le32 opts2;
+	__le32 opts3;
+	__le32 opts4;
+	__le32 opts5;
+	__le32 opts6;
 };
 
 struct tx_desc {
-	u32 opts1;
+	__le32 opts1;
 #define TX_FS			(1 << 31) /* First segment of a packet */
 #define TX_LS			(1 << 30) /* Final segment of a packet */
 #define TX_LEN_MASK		0x3ffff
 
-	u32 opts2;
+	__le32 opts2;
 #define UDP_CS			(1 << 31) /* Calculate UDP/IP checksum */
 #define TCP_CS			(1 << 30) /* Calculate TCP/IP checksum */
 #define IPV4_CS			(1 << 29) /* Calculate IPv4 checksum */
@@ -876,7 +876,7 @@ static void write_bulk_callback(struct urb *urb)
 static void intr_callback(struct urb *urb)
 {
 	struct r8152 *tp;
-	__u16 *d;
+	__le16 *d;
 	int status = urb->status;
 	int res;
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH net v2 2/3] r8152: modify the tx flow
  2013-10-30  7:13   ` [PATCH net v2 2/3] r8152: modify the tx flow Hayes Wang
@ 2013-10-30 21:04     ` David Miller
  2013-10-31  5:52       ` hayeswang
  0 siblings, 1 reply; 15+ messages in thread
From: David Miller @ 2013-10-30 21:04 UTC (permalink / raw)
  To: hayeswang; +Cc: netdev, nic_swsd, linux-kernel, linux-usb

From: Hayes Wang <hayeswang@realtek.com>
Date: Wed, 30 Oct 2013 15:13:39 +0800

> Remove the code for sending the packet in the rtl8152_start_xmit().
> Let rtl8152_start_xmit() to queue the packet only, and schedule a
> tasklet to send the queued packets. This simplify the code and make
> sure all the packet would be sent by the original order.
> 
> Signed-off-by: Hayes Wang <hayeswang@realtek.com>

Basically, your driver will now queue up to 1,000 packets onto
this tx_queue list, because that is what tx_queue_len will be
for alloc_etherdev() allocated network devices.

In my previous reply to you about this patch, I asked you to
quantify and study the effects of using a limit of 60.  I said
that 60 might be too large.

You've responded by removing the limit completely, which is exactly
the opposite of what I've asked you to do.  Why did you do this?

This patch series is still not in a state where I can apply it,
sorry.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: [PATCH net v2 2/3] r8152: modify the tx flow
  2013-10-30 21:04     ` David Miller
@ 2013-10-31  5:52       ` hayeswang
  2013-11-04 20:53         ` David Miller
  0 siblings, 1 reply; 15+ messages in thread
From: hayeswang @ 2013-10-31  5:52 UTC (permalink / raw)
  To: 'David Miller'
  Cc: netdev, 'nic_swsd', linux-kernel, linux-usb

From: David Miller [mailto:davem@davemloft.net] 
Sent: Thursday, October 31, 2013 5:05 AM
> 
> From: Hayes Wang <hayeswang@realtek.com>
> Date: Wed, 30 Oct 2013 15:13:39 +0800
[...]
> Basically, your driver will now queue up to 1,000 packets onto
> this tx_queue list, because that is what tx_queue_len will be
> for alloc_etherdev() allocated network devices.
> 
> In my previous reply to you about this patch, I asked you to
> quantify and study the effects of using a limit of 60.  I said
> that 60 might be too large.
> 
> You've responded by removing the limit completely, which is exactly
> the opposite of what I've asked you to do.  Why did you do this?

Excuse me. My question is that the original code doesn't stop the tx queue
either, so I don't understand why it is necessary for this patch.

I don't say I wouldn't find the suitable value for the tx queue length.
I feel I need some time to think how to find the reasonable value. And
I don't hope it influences the submission of the other patches, so I
remove it first. Or, may I submit the other two patches first?


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net v2 2/3] r8152: modify the tx flow
  2013-10-31  5:52       ` hayeswang
@ 2013-11-04 20:53         ` David Miller
  2013-11-05 12:46           ` hayeswang
  0 siblings, 1 reply; 15+ messages in thread
From: David Miller @ 2013-11-04 20:53 UTC (permalink / raw)
  To: hayeswang; +Cc: netdev, nic_swsd, linux-kernel, linux-usb

From: hayeswang <hayeswang@realtek.com>
Date: Thu, 31 Oct 2013 13:52:38 +0800

> From: David Miller [mailto:davem@davemloft.net] 
> Sent: Thursday, October 31, 2013 5:05 AM
>> 
>> From: Hayes Wang <hayeswang@realtek.com>
>> Date: Wed, 30 Oct 2013 15:13:39 +0800
> [...]
>> Basically, your driver will now queue up to 1,000 packets onto
>> this tx_queue list, because that is what tx_queue_len will be
>> for alloc_etherdev() allocated network devices.
>> 
>> In my previous reply to you about this patch, I asked you to
>> quantify and study the effects of using a limit of 60.  I said
>> that 60 might be too large.
>> 
>> You've responded by removing the limit completely, which is exactly
>> the opposite of what I've asked you to do.  Why did you do this?
> 
> Excuse me. My question is that the original code doesn't stop the tx queue
> either, so I don't understand why it is necessary for this patch.
> 
> I don't say I wouldn't find the suitable value for the tx queue length.
> I feel I need some time to think how to find the reasonable value. And
> I don't hope it influences the submission of the other patches, so I
> remove it first. Or, may I submit the other two patches first?

The more TX work you push into the workqueue handler, the longer the
latency for releasing the SKB and releasing all the queues that are
waiting for release of that packet.

Do you know that sockets, queueing discplines, etc. all rely upon
there being a timely release of SKBs once they are successfully
transmitted?  It must happen at the earliest moment possible that
can be reasonable obtained.


^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: [PATCH net v2 2/3] r8152: modify the tx flow
  2013-11-04 20:53         ` David Miller
@ 2013-11-05 12:46           ` hayeswang
  0 siblings, 0 replies; 15+ messages in thread
From: hayeswang @ 2013-11-05 12:46 UTC (permalink / raw)
  To: 'David Miller'
  Cc: netdev, 'nic_swsd', linux-kernel, linux-usb

 David Miller [mailto:davem@davemloft.net] 
> Sent: Tuesday, November 05, 2013 4:53 AM
> To: Hayeswang
> Cc: netdev@vger.kernel.org; nic_swsd; 
> linux-kernel@vger.kernel.org; linux-usb@vger.kernel.org
> Subject: Re: [PATCH net v2 2/3] r8152: modify the tx flow
[...]
> The more TX work you push into the workqueue handler, the longer the
> latency for releasing the SKB and releasing all the queues that are
> waiting for release of that packet.
> 
> Do you know that sockets, queueing discplines, etc. all rely upon
> there being a timely release of SKBs once they are successfully
> transmitted?  It must happen at the earliest moment possible that
> can be reasonable obtained.

Thanks for your answer. I would resend the patches after finishing the
setting of the queue length.


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2013-11-05 12:46 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-10-29  7:56 [PATCH net 0/3] r8152 bug fixes Hayes Wang
2013-10-29  7:56 ` [PATCH net 1/3] r8152: fix tx/rx memory overflow Hayes Wang
2013-10-29  7:56 ` [PATCH net 2/3] r8152: modify the tx flow Hayes Wang
2013-10-29 21:49   ` David Miller
2013-10-30  3:03     ` hayeswang
2013-10-30  3:08       ` David Miller
2013-10-29  7:56 ` [PATCH net 3/3] r8152: fix incorrect type in assignment Hayes Wang
2013-10-30  7:13 ` [PATCH net v2 0/3] r8152 bug fixes Hayes Wang
2013-10-30  7:13   ` [PATCH net v2 1/3] r8152: fix tx/rx memory overflow Hayes Wang
2013-10-30  7:13   ` [PATCH net v2 2/3] r8152: modify the tx flow Hayes Wang
2013-10-30 21:04     ` David Miller
2013-10-31  5:52       ` hayeswang
2013-11-04 20:53         ` David Miller
2013-11-05 12:46           ` hayeswang
2013-10-30  7:13   ` [PATCH net v2 3/3] r8152: fix incorrect type in assignment Hayes Wang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).