netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: [NET]: Lockless loopback patch (version 2).
       [not found] <200406210510.i5L5A340018849@hera.kernel.org>
@ 2004-06-21 10:57 ` Andrew Morton
  2004-06-21 15:09   ` Arthur Kepner
                     ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Andrew Morton @ 2004-06-21 10:57 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller, akepner

Linux Kernel Mailing List <linux-kernel@vger.kernel.org> wrote:
>
> 	[NET]: Lockless loopback patch (version 2).

The loopback_stats handling looks wrong:

+	if (likely(loopback_stats)) {
+		get_cpu_ptr(loopback_stats)->rx_bytes += skb->len;
+		get_cpu_ptr(loopback_stats)->tx_bytes += skb->len;
+		get_cpu_ptr(loopback_stats)->rx_packets++;
+		get_cpu_ptr(loopback_stats)->tx_packets++;
+		put_cpu_ptr(loopback_stats);

each get_cpu_ptr() does get_cpu(), which increments preempt_count().  But
there is only a single put_cpu_ptr() in there.


Still, I don't see why we need to use alloc_percpu() - why not
statically allocate it?

This compiles, but does need runtime testing.




Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/drivers/net/loopback.c |   35 ++++++++++++++++++-----------------
 1 files changed, 18 insertions(+), 17 deletions(-)

diff -puN drivers/net/loopback.c~loopback-percpu-fix drivers/net/loopback.c
--- 25/drivers/net/loopback.c~loopback-percpu-fix	2004-06-21 03:39:33.265306016 -0700
+++ 25-akpm/drivers/net/loopback.c	2004-06-21 03:50:58.327160784 -0700
@@ -55,8 +55,9 @@
 #include <linux/if_arp.h>	/* For ARPHRD_ETHER */
 #include <linux/ip.h>
 #include <linux/tcp.h>
+#include <linux/percpu.h>
 
-static struct net_device_stats *loopback_stats;
+static DEFINE_PER_CPU(struct net_device_stats, loopback_stats);
 
 #define LOOPBACK_OVERHEAD (128 + MAX_HEADER + 16 + 16)
 
@@ -124,6 +125,7 @@ static void emulate_large_send_offload(s
  */
 static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
 {
+	struct net_device_stats *lb_stats;
 
 	skb_orphan(skb);
 
@@ -142,13 +144,13 @@ static int loopback_xmit(struct sk_buff 
 	}
 
 	dev->last_rx = jiffies;
-	if (likely(loopback_stats)) {
-		get_cpu_ptr(loopback_stats)->rx_bytes += skb->len;
-		get_cpu_ptr(loopback_stats)->tx_bytes += skb->len;
-		get_cpu_ptr(loopback_stats)->rx_packets++;
-		get_cpu_ptr(loopback_stats)->tx_packets++;
-		put_cpu_ptr(loopback_stats);
-	}
+
+	lb_stats = &per_cpu(loopback_stats, get_cpu());
+	lb_stats->rx_bytes += skb->len;
+	lb_stats->tx_bytes += skb->len;
+	lb_stats->rx_packets++;
+	lb_stats->tx_packets++;
+	put_cpu();
 
 	netif_rx(skb);
 
@@ -165,17 +167,18 @@ static struct net_device_stats *get_stat
 	}
 
 	memset(stats, 0, sizeof(struct net_device_stats));
-	if (!loopback_stats) {
-		return stats;
-	}
 
 	for (i=0; i < NR_CPUS; i++) {
+		struct net_device_stats *lb_stats;
+
 		if (!cpu_possible(i)) 
 			continue;
-		stats->rx_bytes   += per_cpu_ptr(loopback_stats, i)->rx_bytes;
-		stats->tx_bytes   += per_cpu_ptr(loopback_stats, i)->tx_bytes;
-		stats->rx_packets += per_cpu_ptr(loopback_stats, i)->rx_packets;
-		stats->tx_packets += per_cpu_ptr(loopback_stats, i)->tx_packets;
+		lb_stats = &per_cpu(loopback_stats, get_cpu());
+		stats->rx_bytes   += lb_stats->rx_bytes;
+		stats->tx_bytes   += lb_stats->tx_bytes;
+		stats->rx_packets += lb_stats->rx_packets;
+		stats->tx_packets += lb_stats->tx_packets;
+		put_cpu();
 	}
 				
 	return stats;
@@ -211,8 +214,6 @@ int __init loopback_init(void)
 		loopback_dev.priv = stats;
 		loopback_dev.get_stats = &get_stats;
 	}
-
-	loopback_stats = alloc_percpu(struct net_device_stats);
 	
 	return register_netdev(&loopback_dev);
 };
_

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

* Re: [NET]: Lockless loopback patch (version 2).
  2004-06-21 10:57 ` [NET]: Lockless loopback patch (version 2) Andrew Morton
@ 2004-06-21 15:09   ` Arthur Kepner
  2004-06-21 16:39   ` David S. Miller
  2004-06-22 16:24   ` [PATCH] preempt count regression w/ lockless loopback patch Arthur Kepner
  2 siblings, 0 replies; 7+ messages in thread
From: Arthur Kepner @ 2004-06-21 15:09 UTC (permalink / raw)
  To: Andrew Morton; +Cc: netdev, David S. Miller

On Mon, 21 Jun 2004, Andrew Morton wrote:

> Linux Kernel Mailing List <linux-kernel@vger.kernel.org> wrote:
> >
> > 	[NET]: Lockless loopback patch (version 2).
>
> The loopback_stats handling looks wrong:
>
> ....
> each get_cpu_ptr() does get_cpu(), which increments preempt_count().  But
> there is only a single put_cpu_ptr() in there.
>
>
> Still, I don't see why we need to use alloc_percpu() - why not
> statically allocate it?
>
> This compiles, but does need runtime testing.

Thanks, Andrew. I'll do some basic testing of this change and
post results (probably by tomorrow.)

--

Arthur

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

* Re: [NET]: Lockless loopback patch (version 2).
  2004-06-21 10:57 ` [NET]: Lockless loopback patch (version 2) Andrew Morton
  2004-06-21 15:09   ` Arthur Kepner
@ 2004-06-21 16:39   ` David S. Miller
  2004-06-22 16:24   ` [PATCH] preempt count regression w/ lockless loopback patch Arthur Kepner
  2 siblings, 0 replies; 7+ messages in thread
From: David S. Miller @ 2004-06-21 16:39 UTC (permalink / raw)
  To: Andrew Morton; +Cc: netdev, akepner

On Mon, 21 Jun 2004 03:57:02 -0700
Andrew Morton <akpm@osdl.org> wrote:

> Still, I don't see why we need to use alloc_percpu() - why not
> statically allocate it?
> 
> This compiles, but does need runtime testing.

Looks good to me, applied.

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

* [PATCH] preempt count regression w/ lockless loopback patch
  2004-06-21 10:57 ` [NET]: Lockless loopback patch (version 2) Andrew Morton
  2004-06-21 15:09   ` Arthur Kepner
  2004-06-21 16:39   ` David S. Miller
@ 2004-06-22 16:24   ` Arthur Kepner
  2004-06-22 19:39     ` David S. Miller
  2 siblings, 1 reply; 7+ messages in thread
From: Arthur Kepner @ 2004-06-22 16:24 UTC (permalink / raw)
  To: Andrew Morton; +Cc: netdev, David S. Miller, Chris Wright, Bob Gill

[-- Attachment #1: Type: TEXT/PLAIN, Size: 548 bytes --]


On Mon, 21 Jun 2004, Andrew Morton wrote:

> The loopback_stats handling looks wrong:
> .....
>
> each get_cpu_ptr() does get_cpu(), which increments preempt_count().  But
> there is only a single put_cpu_ptr() in there.

Correct. At least one person has tripped over this already. (See "Re:
[2.6.7-bk] NFS-related kernel panic" on lkml.)

> .....
>
> This compiles, but does need runtime testing.
>

I made one small change in get_stats() and tested with a preemptible
kernel on a 32p system. Looks good. The tested patch is attached.

--

Arthur

[-- Attachment #2: patch for preempt count bug --]
[-- Type: TEXT/PLAIN, Size: 2162 bytes --]

--- linux.tmp/drivers/net/loopback.c	2004-06-22 09:00:41.000000000 -0700
+++ linux/drivers/net/loopback.c	2004-06-22 09:06:41.000000000 -0700
@@ -55,8 +55,9 @@
 #include <linux/if_arp.h>	/* For ARPHRD_ETHER */
 #include <linux/ip.h>
 #include <linux/tcp.h>
+#include <linux/percpu.h>
 
-static struct net_device_stats *loopback_stats;
+static DEFINE_PER_CPU(struct net_device_stats, loopback_stats);
 
 #define LOOPBACK_OVERHEAD (128 + MAX_HEADER + 16 + 16)
 
@@ -124,6 +125,7 @@
  */
 static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
 {
+	struct net_device_stats *lb_stats;
 
 	skb_orphan(skb);
 
@@ -142,13 +144,12 @@
 	}
 
 	dev->last_rx = jiffies;
-	if (likely(loopback_stats)) {
-		get_cpu_ptr(loopback_stats)->rx_bytes += skb->len;
-		get_cpu_ptr(loopback_stats)->tx_bytes += skb->len;
-		get_cpu_ptr(loopback_stats)->rx_packets++;
-		get_cpu_ptr(loopback_stats)->tx_packets++;
-		put_cpu_ptr(loopback_stats);
-	}
+	lb_stats = &per_cpu(loopback_stats, get_cpu());
+	lb_stats->rx_bytes += skb->len;
+	lb_stats->tx_bytes += skb->len;
+	lb_stats->rx_packets++;
+	lb_stats->tx_packets++;
+	put_cpu();
 
 	netif_rx(skb);
 
@@ -165,19 +166,19 @@
 	}
 
 	memset(stats, 0, sizeof(struct net_device_stats));
-	if (!loopback_stats) {
-		return stats;
-	}
 
 	for (i=0; i < NR_CPUS; i++) {
+		struct net_device_stats *lb_stats;
+
 		if (!cpu_possible(i)) 
 			continue;
-		stats->rx_bytes   += per_cpu_ptr(loopback_stats, i)->rx_bytes;
-		stats->tx_bytes   += per_cpu_ptr(loopback_stats, i)->tx_bytes;
-		stats->rx_packets += per_cpu_ptr(loopback_stats, i)->rx_packets;
-		stats->tx_packets += per_cpu_ptr(loopback_stats, i)->tx_packets;
+		lb_stats = &per_cpu(loopback_stats, i);
+		stats->rx_bytes   += lb_stats->rx_bytes;
+		stats->tx_bytes   += lb_stats->tx_bytes;
+		stats->rx_packets += lb_stats->rx_packets;
+		stats->tx_packets += lb_stats->tx_packets;
 	}
-				
+
 	return stats;
 }
 
@@ -212,8 +213,6 @@
 		loopback_dev.get_stats = &get_stats;
 	}
 
-	loopback_stats = alloc_percpu(struct net_device_stats);
-	
 	return register_netdev(&loopback_dev);
 };
 

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

* Re: [PATCH] preempt count regression w/ lockless loopback patch
  2004-06-22 16:24   ` [PATCH] preempt count regression w/ lockless loopback patch Arthur Kepner
@ 2004-06-22 19:39     ` David S. Miller
  2004-06-22 20:46       ` Arthur Kepner
  0 siblings, 1 reply; 7+ messages in thread
From: David S. Miller @ 2004-06-22 19:39 UTC (permalink / raw)
  To: Arthur Kepner; +Cc: akpm, netdev, chrisw, gillb4

On Tue, 22 Jun 2004 09:24:40 -0700
Arthur Kepner <akepner@sgi.com> wrote:

> I made one small change in get_stats() and tested with a preemptible
> kernel on a 32p system. Looks good. The tested patch is attached.

Can you instead give a patch relative to Andrew's?  His is
applied already and in fact pushed into Linus's tree.

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

* Re: [PATCH] preempt count regression w/ lockless loopback patch
  2004-06-22 19:39     ` David S. Miller
@ 2004-06-22 20:46       ` Arthur Kepner
  2004-06-22 21:01         ` David S. Miller
  0 siblings, 1 reply; 7+ messages in thread
From: Arthur Kepner @ 2004-06-22 20:46 UTC (permalink / raw)
  To: David S. Miller; +Cc: akpm, netdev, chrisw, gillb4

[-- Attachment #1: Type: TEXT/PLAIN, Size: 213 bytes --]

On Tue, 22 Jun 2004, David S. Miller wrote:

> ....
> Can you instead give a patch relative to Andrew's?  His is
> applied already and in fact pushed into Linus's tree.
>

Yes. It is in the attachment.

--

Arthur

[-- Attachment #2: patch relative to akpm --]
[-- Type: TEXT/PLAIN, Size: 537 bytes --]

--- linux.akpm/drivers/net/loopback.c	2004-06-22 13:35:13.000000000 -0700
+++ linux/drivers/net/loopback.c	2004-06-22 13:42:27.000000000 -0700
@@ -173,12 +173,11 @@
 
 		if (!cpu_possible(i)) 
 			continue;
-		lb_stats = &per_cpu(loopback_stats, get_cpu());
+		lb_stats = &per_cpu(loopback_stats, i);
 		stats->rx_bytes   += lb_stats->rx_bytes;
 		stats->tx_bytes   += lb_stats->tx_bytes;
 		stats->rx_packets += lb_stats->rx_packets;
 		stats->tx_packets += lb_stats->tx_packets;
-		put_cpu();
 	}
 				
 	return stats;

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

* Re: [PATCH] preempt count regression w/ lockless loopback patch
  2004-06-22 20:46       ` Arthur Kepner
@ 2004-06-22 21:01         ` David S. Miller
  0 siblings, 0 replies; 7+ messages in thread
From: David S. Miller @ 2004-06-22 21:01 UTC (permalink / raw)
  To: Arthur Kepner; +Cc: akpm, netdev, chrisw, gillb4

On Tue, 22 Jun 2004 13:46:07 -0700
Arthur Kepner <akepner@sgi.com> wrote:

> On Tue, 22 Jun 2004, David S. Miller wrote:
> 
> > ....
> > Can you instead give a patch relative to Andrew's?  His is
> > applied already and in fact pushed into Linus's tree.
> >
> 
> Yes. It is in the attachment.

Thanks a lot Arthur, patch applied.

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

end of thread, other threads:[~2004-06-22 21:01 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <200406210510.i5L5A340018849@hera.kernel.org>
2004-06-21 10:57 ` [NET]: Lockless loopback patch (version 2) Andrew Morton
2004-06-21 15:09   ` Arthur Kepner
2004-06-21 16:39   ` David S. Miller
2004-06-22 16:24   ` [PATCH] preempt count regression w/ lockless loopback patch Arthur Kepner
2004-06-22 19:39     ` David S. Miller
2004-06-22 20:46       ` Arthur Kepner
2004-06-22 21:01         ` David S. Miller

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).