Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH, netfilter] NUMA aware ipv4/netfilter/ip_tables.c
From: Andi Kleen @ 2005-09-20 16:30 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev, netfilter-devel
In-Reply-To: <432FDAC5.3040801@cosmosbay.com>

On Tuesday 20 September 2005 11:47, Eric Dumazet wrote:
> +#ifdef CONFIG_NUMA
> +                       struct mempolicy *oldpol;
> +                       struct mempolicy prefnodepolicy = {
> +                               .refcnt = ATOMIC_INIT(1),
> +                               .policy = MPOL_PREFERRED,
> +                               .v.preferred_node = cpu_to_node(cpu),
> +                       };
> +                       oldpol = current->mempolicy;
> +                       current->mempolicy = &prefnodepolicy;
> +#endif

I would prefer if random code didn't mess with mempolicy internals
like this. Better just call sys_set_mempolicy() 

-Andi

^ permalink raw reply

* Re: TCP throttling
From: Stephen Hemminger @ 2005-09-20 16:19 UTC (permalink / raw)
  To: Mikael Abrahamsson; +Cc: Al Boldi, linux-net, netdev
In-Reply-To: <Pine.LNX.4.62.0509200717410.21650@uplift.swm.pp.se>

On Tue, 20 Sep 2005 07:19:03 +0200 (CEST)
Mikael Abrahamsson <swmike@swm.pp.se> wrote:

> On Tue, 20 Sep 2005, Al Boldi wrote:
> 
> > Could you suggest sane values for 2.4/2.6 on a 100mbit link?
> 
> Go for approx 2-8 megs of TCP window size and buffers.

I use the following for testing over 1GE. You want
at least 2x the delay bandwidth product.

/etc/sysctl.conf
# increase Linux TCP buffer limits
net.core.rmem_max = 8388608
net.core.wmem_max = 8388608

# increase Linux autotuning TCP buffer limits
net.ipv4.tcp_rmem = 4096 87380 8388608
net.ipv4.tcp_wmem = 4096 65536 8388608

^ permalink raw reply

* Re: workaround large MTU and N-order allocation failures
From: Dan Aloni @ 2005-09-20 14:34 UTC (permalink / raw)
  To: Nick Piggin; +Cc: lkml, netdev
In-Reply-To: <1127111462.5272.7.camel@npiggin-nld.site>

On Mon, Sep 19, 2005 at 04:31:02PM +1000, Nick Piggin wrote:
> On Sun, 2005-09-18 at 17:35 +0300, Dan Aloni wrote:
> > Hello,
> > 
> > Is there currently a workaround available for handling large MTU 
> > (larger than 1 page, even 2-order) in the Linux network stack?
> > 
> > The problem with large MTU is external memory fragmentation in
> > the buddy system following high workload, causing alloc_skb() to 
> > fail.
> > 
> > I'm interested in patches for both 2.4 and 2.6 kernels.
> > 
> 
> Yes there is currently a workaround. That is to keep increasing
> /proc/sys/vm/min_free_kbytes until your allocation failures stop.

We have developed a much more reliable workaround which works on both
the 2.4 and 2.6 trees. 

Our development is called 'Pre-allocated Big Buffers', basically prebb 
provides fixed-sized pools of fixed-size blocks that are allocated during
boot time using the bootmem allocator (thus are disconnected from the 
slab cache completely). block size need not to be page aligned. It is 
possible to allocate these blocks at O(1) efficiency at any context.

Each pool has a minimum and maximum object size (where allocations 
should strive to be the maximum for memory usage efficiency). Currently 
we use prebb to ensure no fragmentation and fine-tuned memory usage.

(Of course a few changes inside net/core/skbuff.c were needed for 
skb buffers to allocate from prebb instead of slab).

-- 
Dan Aloni
da-x@monatomic.org, da-x@colinux.org, da-x@gmx.net

^ permalink raw reply

* Re: workaround large MTU and N-order allocation failures
From: Dan Aloni @ 2005-09-20 14:25 UTC (permalink / raw)
  To: Ganesh Venkatesan; +Cc: Francois Romieu, Linux Kernel List, netdev, Nick Piggin
In-Reply-To: <5fc59ff305091910252447d363@mail.gmail.com>

On Mon, Sep 19, 2005 at 10:25:29AM -0700, Ganesh Venkatesan wrote:
> 82546GB supports an incoming Rx packet to be received in multiple rx
> buffers. A driver that enables this feature is under test currently.
> What version of the e1000 are you using?

We are currently using the lastest version of the driver from the 2.6 
tree backported to the 2.4 tree. I wasn't aware that 82546GB supports 
this - I inferred differently from the comments in the driver's source.

Is the version of the driver you mention available from CVS somewhere?

-- 
Dan Aloni
da-x@monatomic.org, da-x@colinux.org, da-x@gmx.net

^ permalink raw reply

* [patch] fix suspend/resume on b44
From: Pavel Machek @ 2005-09-20 13:28 UTC (permalink / raw)
  To: Andrew Morton, Jeff Garzik, Netdev list

Fix suspend/resume on b44 by freeing/reacquiring irq. Otherwise it
hangs on resume.

Signed-off-by: Pavel Machek <pavel@suse.cz>

---
commit 7bdc8fc378f053bd4eb4210beb1d494485318512
tree 6e5679697b11eb70b73ff5275aafe7c34a90ffef
parent 17cd36a6d0fc36b61fa558cade6a98a3e99a6992
author <pavel@amd.(none)> Tue, 20 Sep 2005 15:26:37 +0200
committer <pavel@amd.(none)> Tue, 20 Sep 2005 15:26:37 +0200

 drivers/net/b44.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/net/b44.c b/drivers/net/b44.c
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -1930,6 +1930,8 @@ static int b44_suspend(struct pci_dev *p
 	b44_free_rings(bp);
 
 	spin_unlock_irq(&bp->lock);
+
+	free_irq(dev->irq, dev);
 	pci_disable_device(pdev);
 	return 0;
 }
@@ -1946,6 +1948,9 @@ static int b44_resume(struct pci_dev *pd
 	if (!netif_running(dev))
 		return 0;
 
+	if (request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev))
+		printk(KERN_ERR PFX "%s: request_irq failed\n", dev->name);
+
 	spin_lock_irq(&bp->lock);
 
 	b44_init_rings(bp);

-- 
if you have sharp zaurus hardware you don't need... you know my address

^ permalink raw reply

* Re: [PATCH, netfilter] NUMA aware ipv4/netfilter/ip_tables.c
From: Eric Dumazet @ 2005-09-20  9:47 UTC (permalink / raw)
  To: netfilter-devel; +Cc: netdev, Andi Kleen
In-Reply-To: <200509191948.55333.ak@suse.de>

[-- Attachment #1: Type: text/plain, Size: 1032 bytes --]

Hi all

Part of the performance problem we have with netfilter is memory allocation is 
not NUMA aware, but 'only' SMP aware (ie each CPU normally touch separate 
cache lines)

Even with small iptables rules, the cost of this misplacement can be high on 
common workloads.

Instead of using one vmalloc() area (located in the node of the iptables 
process), we now vmalloc() an area for each possible CPU, using NUMA policy 
(MPOL_PREFERRED) so that memory should be allocated in the CPU's node if possible.

If the size of ipt_table is small enough (less than one page), we use 
kmalloc_node() instead of vmalloc(), to use less memory (and less TLB entries) 
in small setups.

This patch try to use local node memory in expensive translate_table() 
function (and others), but doesnt bother to bind the task to the current CPU.

Note : I also optimize get_counters(), using a SET_COUNTER() for the first 
cpu, avoiding a memset() and ADD_COUNTER() if SMP on other cpus.

Thank you

Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>

[-- Attachment #2: patch_ip_tables_numa --]
[-- Type: text/plain, Size: 13267 bytes --]

--- linux-2.6.14-rc1.p1/net/ipv4/netfilter/ip_tables.c	2005-09-19 19:56:12.000000000 +0200
+++ linux-2.6.14-rc1/net/ipv4/netfilter/ip_tables.c	2005-09-20 13:41:37.000000000 +0200
@@ -17,6 +17,7 @@
 #include <linux/skbuff.h>
 #include <linux/kmod.h>
 #include <linux/vmalloc.h>
+#include <linux/mempolicy.h>
 #include <linux/netdevice.h>
 #include <linux/module.h>
 #include <linux/tcp.h>
@@ -82,11 +83,6 @@
    context stops packets coming through and allows user context to read
    the counters or update the rules.
 
-   To be cache friendly on SMP, we arrange them like so:
-   [ n-entries ]
-   ... cache-align padding ...
-   [ n-entries ]
-
    Hence the start of any table is given by get_table() below.  */
 
 /* The table itself */
@@ -104,19 +100,14 @@
 	unsigned int underflow[NF_IP_NUMHOOKS];
 
 	/* ipt_entry tables: one per CPU */
-	char entries[0] ____cacheline_aligned;
+	void *entries[NR_CPUS];
 };
 
 static LIST_HEAD(ipt_target);
 static LIST_HEAD(ipt_match);
 static LIST_HEAD(ipt_tables);
 #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0)
-
-#ifdef CONFIG_SMP
-#define TABLE_OFFSET(t,p) (SMP_ALIGN((t)->size)*(p))
-#else
-#define TABLE_OFFSET(t,p) 0
-#endif
+#define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0)
 
 #if 0
 #define down(x) do { printk("DOWN:%u:" #x "\n", __LINE__); down(x); } while(0)
@@ -289,8 +280,7 @@
 
 	read_lock_bh(&table->lock);
 	IP_NF_ASSERT(table->valid_hooks & (1 << hook));
-	table_base = (void *)table->private->entries
-		+ TABLE_OFFSET(table->private, smp_processor_id());
+	table_base = (void *)table->private->entries[smp_processor_id()];
 	e = get_entry(table_base, table->private->hook_entry[hook]);
 
 #ifdef CONFIG_NETFILTER_DEBUG
@@ -562,7 +552,7 @@
 /* Figures out from what hook each rule can be called: returns 0 if
    there are loops.  Puts hook bitmask in comefrom. */
 static int
-mark_source_chains(struct ipt_table_info *newinfo, unsigned int valid_hooks)
+mark_source_chains(struct ipt_table_info *newinfo, unsigned int valid_hooks, void *entry0)
 {
 	unsigned int hook;
 
@@ -571,7 +561,7 @@
 	for (hook = 0; hook < NF_IP_NUMHOOKS; hook++) {
 		unsigned int pos = newinfo->hook_entry[hook];
 		struct ipt_entry *e
-			= (struct ipt_entry *)(newinfo->entries + pos);
+			= (struct ipt_entry *)(entry0 + pos);
 
 		if (!(valid_hooks & (1 << hook)))
 			continue;
@@ -621,13 +611,13 @@
 						goto next;
 
 					e = (struct ipt_entry *)
-						(newinfo->entries + pos);
+						(entry0 + pos);
 				} while (oldpos == pos + e->next_offset);
 
 				/* Move along one */
 				size = e->next_offset;
 				e = (struct ipt_entry *)
-					(newinfo->entries + pos + size);
+					(entry0 + pos + size);
 				e->counters.pcnt = pos;
 				pos += size;
 			} else {
@@ -644,7 +634,7 @@
 					newpos = pos + e->next_offset;
 				}
 				e = (struct ipt_entry *)
-					(newinfo->entries + newpos);
+					(entry0 + newpos);
 				e->counters.pcnt = pos;
 				pos = newpos;
 			}
@@ -854,6 +844,7 @@
 translate_table(const char *name,
 		unsigned int valid_hooks,
 		struct ipt_table_info *newinfo,
+		void *entry0,
 		unsigned int size,
 		unsigned int number,
 		const unsigned int *hook_entries,
@@ -874,11 +865,11 @@
 	duprintf("translate_table: size %u\n", newinfo->size);
 	i = 0;
 	/* Walk through entries, checking offsets. */
-	ret = IPT_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+	ret = IPT_ENTRY_ITERATE(entry0, newinfo->size,
 				check_entry_size_and_hooks,
 				newinfo,
-				newinfo->entries,
-				newinfo->entries + size,
+				entry0,
+				entry0 + size,
 				hook_entries, underflows, &i);
 	if (ret != 0)
 		return ret;
@@ -906,25 +897,24 @@
 		}
 	}
 
-	if (!mark_source_chains(newinfo, valid_hooks))
+	if (!mark_source_chains(newinfo, valid_hooks, entry0))
 		return -ELOOP;
 
 	/* Finally, each sanity check must pass */
 	i = 0;
-	ret = IPT_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+	ret = IPT_ENTRY_ITERATE(entry0, newinfo->size,
 				check_entry, name, size, &i);
 
 	if (ret != 0) {
-		IPT_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+		IPT_ENTRY_ITERATE(entry0, newinfo->size,
 				  cleanup_entry, &i);
 		return ret;
 	}
 
 	/* And one copy for every other CPU */
-	for (i = 1; i < num_possible_cpus(); i++) {
-		memcpy(newinfo->entries + SMP_ALIGN(newinfo->size)*i,
-		       newinfo->entries,
-		       SMP_ALIGN(newinfo->size));
+	for_each_cpu(i) {
+		if (newinfo->entries[i] && newinfo->entries[i] != entry0)
+			memcpy(newinfo->entries[i], entry0, newinfo->size);
 	}
 
 	return ret;
@@ -940,15 +930,12 @@
 
 #ifdef CONFIG_NETFILTER_DEBUG
 	{
-		struct ipt_entry *table_base;
-		unsigned int i;
+		int cpu;
 
-		for (i = 0; i < num_possible_cpus(); i++) {
-			table_base =
-				(void *)newinfo->entries
-				+ TABLE_OFFSET(newinfo, i);
-
-			table_base->comefrom = 0xdead57ac;
+		for_each_cpu(cpu) {
+			struct ipt_entry *table_base = newinfo->entries[cpu];
+			if (table_base)
+				table_base->comefrom = 0xdead57ac;
 		}
 	}
 #endif
@@ -972,6 +959,7 @@
 }
 
 /* Gets counters. */
+#ifdef CONFIG_SMP
 static inline int
 add_entry_to_counter(const struct ipt_entry *e,
 		     struct ipt_counters total[],
@@ -982,22 +970,44 @@
 	(*i)++;
 	return 0;
 }
+#endif
+static inline int
+set_entry_to_counter(const struct ipt_entry *e,
+		     struct ipt_counters total[],
+		     unsigned int *i)
+{
+	SET_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt);
+
+	(*i)++;
+	return 0;
+}
 
 static void
 get_counters(const struct ipt_table_info *t,
 	     struct ipt_counters counters[])
 {
 	unsigned int cpu;
+	unsigned int curcpu = raw_smp_processor_id();
 	unsigned int i;
 
-	for (cpu = 0; cpu < num_possible_cpus(); cpu++) {
+	i = 0;
+	IPT_ENTRY_ITERATE(t->entries[curcpu],
+			  t->size,
+			  set_entry_to_counter,
+			  counters,
+			  &i);
+#ifdef CONFIG_SMP
+	for_each_cpu(cpu) {
+		if (cpu == curcpu)
+			continue;
 		i = 0;
-		IPT_ENTRY_ITERATE(t->entries + TABLE_OFFSET(t, cpu),
+		IPT_ENTRY_ITERATE(t->entries[cpu],
 				  t->size,
 				  add_entry_to_counter,
 				  counters,
 				  &i);
 	}
+#endif
 }
 
 static int
@@ -1009,6 +1019,7 @@
 	struct ipt_entry *e;
 	struct ipt_counters *counters;
 	int ret = 0;
+	void *loc_cpu_entry;
 
 	/* We need atomic snapshot of counters: rest doesn't change
 	   (other than comefrom, which userspace doesn't care
@@ -1020,13 +1031,17 @@
 		return -ENOMEM;
 
 	/* First, sum counters... */
-	memset(counters, 0, countersize);
 	write_lock_bh(&table->lock);
 	get_counters(table->private, counters);
 	write_unlock_bh(&table->lock);
 
-	/* ... then copy entire thing from CPU 0... */
-	if (copy_to_user(userptr, table->private->entries, total_size) != 0) {
+	/*
+	 * choose the copy that is on our node,
+	 * but dont worry if the scheduler changes the CPU
+	 */
+	loc_cpu_entry = table->private->entries[raw_smp_processor_id()];
+	/* ... then copy entire thing ... */
+	if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) {
 		ret = -EFAULT;
 		goto free_counters;
 	}
@@ -1038,7 +1053,7 @@
 		struct ipt_entry_match *m;
 		struct ipt_entry_target *t;
 
-		e = (struct ipt_entry *)(table->private->entries + off);
+		e = (struct ipt_entry *)(loc_cpu_entry + off);
 		if (copy_to_user(userptr + off
 				 + offsetof(struct ipt_entry, counters),
 				 &counters[num],
@@ -1107,6 +1122,56 @@
 	return ret;
 }
 
+static void free_table_info(struct ipt_table_info *info)
+{
+	int cpu;
+	for_each_cpu(cpu) {
+		if (info->size <= PAGE_SIZE)
+			kfree(info->entries[cpu]);
+		else
+			vfree(info->entries[cpu]);
+	}
+	kfree(info);
+}
+
+static struct ipt_table_info *alloc_table_info(unsigned int size)
+{
+struct ipt_table_info *newinfo;
+int cpu;
+	newinfo = kzalloc(sizeof(struct ipt_table_info), GFP_KERNEL);
+	if (!newinfo)
+		return NULL;
+	newinfo->size = size;
+	for_each_cpu(cpu) {
+		if (size <= PAGE_SIZE) {
+			newinfo->entries[cpu] = kmalloc_node(size,
+				GFP_KERNEL,
+				cpu_to_node(cpu));
+		} else {
+#ifdef CONFIG_NUMA
+			struct mempolicy *oldpol;
+			struct mempolicy prefnodepolicy = {
+				.refcnt = ATOMIC_INIT(1),
+				.policy = MPOL_PREFERRED,
+				.v.preferred_node = cpu_to_node(cpu),
+			};
+			oldpol = current->mempolicy;
+			current->mempolicy = &prefnodepolicy;
+#endif
+			newinfo->entries[cpu] = vmalloc(size);
+#ifdef CONFIG_NUMA
+			current->mempolicy = oldpol;
+#endif
+		}
+		if (newinfo->entries[cpu] == 0) {
+			free_table_info(newinfo);
+			return NULL;
+		}
+	}
+	return newinfo;
+}
+
+
 static int
 do_replace(void __user *user, unsigned int len)
 {
@@ -1115,6 +1180,7 @@
 	struct ipt_table *t;
 	struct ipt_table_info *newinfo, *oldinfo;
 	struct ipt_counters *counters;
+	void *loc_cpu_entry, *loc_cpu_old_entry;
 
 	if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
 		return -EFAULT;
@@ -1127,12 +1193,15 @@
 	if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages)
 		return -ENOMEM;
 
-	newinfo = vmalloc(sizeof(struct ipt_table_info)
-			  + SMP_ALIGN(tmp.size) * num_possible_cpus());
+	newinfo = alloc_table_info(tmp.size);
 	if (!newinfo)
 		return -ENOMEM;
-
-	if (copy_from_user(newinfo->entries, user + sizeof(tmp),
+	/*
+	 * choose the copy that is on our node,
+	 * but dont worry if the scheduler changes the CPU
+	 */
+	loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
+	if (copy_from_user(loc_cpu_entry, user + sizeof(tmp),
 			   tmp.size) != 0) {
 		ret = -EFAULT;
 		goto free_newinfo;
@@ -1143,10 +1212,9 @@
 		ret = -ENOMEM;
 		goto free_newinfo;
 	}
-	memset(counters, 0, tmp.num_counters * sizeof(struct ipt_counters));
 
 	ret = translate_table(tmp.name, tmp.valid_hooks,
-			      newinfo, tmp.size, tmp.num_entries,
+			      newinfo, loc_cpu_entry, tmp.size, tmp.num_entries,
 			      tmp.hook_entry, tmp.underflow);
 	if (ret != 0)
 		goto free_newinfo_counters;
@@ -1185,8 +1253,9 @@
 	/* Get the old counters. */
 	get_counters(oldinfo, counters);
 	/* Decrease module usage counts and free resource */
-	IPT_ENTRY_ITERATE(oldinfo->entries, oldinfo->size, cleanup_entry,NULL);
-	vfree(oldinfo);
+	loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()];
+	IPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL);
+	free_table_info(oldinfo);
 	if (copy_to_user(tmp.counters, counters,
 			 sizeof(struct ipt_counters) * tmp.num_counters) != 0)
 		ret = -EFAULT;
@@ -1198,11 +1267,11 @@
 	module_put(t->me);
 	up(&ipt_mutex);
  free_newinfo_counters_untrans:
-	IPT_ENTRY_ITERATE(newinfo->entries, newinfo->size, cleanup_entry,NULL);
+	IPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL);
  free_newinfo_counters:
 	vfree(counters);
  free_newinfo:
-	vfree(newinfo);
+	free_table_info(newinfo);
 	return ret;
 }
 
@@ -1235,6 +1304,7 @@
 	struct ipt_counters_info tmp, *paddc;
 	struct ipt_table *t;
 	int ret = 0;
+	void *loc_cpu_entry;
 
 	if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
 		return -EFAULT;
@@ -1264,7 +1334,12 @@
 	}
 
 	i = 0;
-	IPT_ENTRY_ITERATE(t->private->entries,
+	/*
+	 * choose the copy that is on our node,
+	 * but dont worry if the scheduler changes the CPU
+	 */
+	loc_cpu_entry = t->private->entries[raw_smp_processor_id()];
+	IPT_ENTRY_ITERATE(loc_cpu_entry,
 			  t->private->size,
 			  add_counter_to_entry,
 			  paddc->counters,
@@ -1454,29 +1529,39 @@
 {
 	int ret;
 	struct ipt_table_info *newinfo;
-	static struct ipt_table_info bootstrap
-		= { 0, 0, 0, { 0 }, { 0 }, { } };
+	static struct ipt_table_info bootstrap = {
+		.size = 0,
+		.number = 0,
+		.initial_entries = 0,
+		.hook_entry = { 0 },
+		.underflow = { 0 },
+		.entries = {NULL }
+		};
+	void *loc_cpu_entry;
 
-	newinfo = vmalloc(sizeof(struct ipt_table_info)
-			  + SMP_ALIGN(repl->size) * num_possible_cpus());
+	newinfo = alloc_table_info(repl->size);
 	if (!newinfo)
 		return -ENOMEM;
-
-	memcpy(newinfo->entries, repl->entries, repl->size);
+	/*
+	 * choose the copy that is on our node,
+	 * but dont worry if the scheduler changes the CPU
+	 */
+	loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
+	memcpy(loc_cpu_entry, repl->entries, repl->size);
 
 	ret = translate_table(table->name, table->valid_hooks,
-			      newinfo, repl->size,
+			      newinfo, loc_cpu_entry, repl->size,
 			      repl->num_entries,
 			      repl->hook_entry,
 			      repl->underflow);
 	if (ret != 0) {
-		vfree(newinfo);
+		free_table_info(newinfo);
 		return ret;
 	}
 
 	ret = down_interruptible(&ipt_mutex);
 	if (ret != 0) {
-		vfree(newinfo);
+		free_table_info(newinfo);
 		return ret;
 	}
 
@@ -1505,20 +1590,25 @@
 	return ret;
 
  free_unlock:
-	vfree(newinfo);
+	free_table_info(newinfo);
 	goto unlock;
 }
 
 void ipt_unregister_table(struct ipt_table *table)
 {
+	void *loc_cpu_entry;
 	down(&ipt_mutex);
 	LIST_DELETE(&ipt_tables, table);
 	up(&ipt_mutex);
 
-	/* Decrease module usage counts and free resources */
-	IPT_ENTRY_ITERATE(table->private->entries, table->private->size,
+	/* Decrease module usage counts and free resources
+	 * choose the copy that is on our node,
+	 * but dont worry if the scheduler changes the CPU
+	 */
+	loc_cpu_entry = table->private->entries[raw_smp_processor_id()];
+	IPT_ENTRY_ITERATE(loc_cpu_entry, table->private->size,
 			  cleanup_entry, NULL);
-	vfree(table->private);
+	free_table_info(table->private);
 }
 
 /* Returns 1 if the port is matched by the range, 0 otherwise */

^ permalink raw reply

* Re: TCP throttling
From: Mikael Abrahamsson @ 2005-09-20  5:19 UTC (permalink / raw)
  To: Al Boldi; +Cc: Stephen Hemminger, linux-net, netdev
In-Reply-To: <200509200654.23703.a1426z@gawab.com>

On Tue, 20 Sep 2005, Al Boldi wrote:

> Could you suggest sane values for 2.4/2.6 on a 100mbit link?

Go for approx 2-8 megs of TCP window size and buffers.

-- 
Mikael Abrahamsson    email: swmike@swm.pp.se

^ permalink raw reply

* Re: TCP throttling
From: Arnaldo Carvalho de Melo @ 2005-09-20  4:44 UTC (permalink / raw)
  To: Al Boldi; +Cc: Stephen Hemminger, linux-net, netdev
In-Reply-To: <200509200654.23703.a1426z@gawab.com>

On 9/20/05, Al Boldi <a1426z@gawab.com> wrote:
> Stephen Hemminger wrote:
> > You probably need to increase the maximum socket buffer
> > sizes.  Linux defaults are conservative to avoid running
> > servers out of memory.
> >
> > http://www.psc.edu/networking/projects/tcptune/#Linux
> 
> Thanks for the great link! It kept me up all night.
> 
> I managed to crash the server running out of memory.  Don't ask what numbers
> I used, I just went overboard.  I played with these numbers before, but
> never imagined that their scale would be in the millions.
> 
> Could you suggest sane values for 2.4/2.6 on a 100mbit link?

Well, perhaps the sane, conservative values are the one already calculated
by the kernel? Just add more memory to your machine and the sane values will
go up accordingly? :-)

- Arnaldo

^ permalink raw reply

* Re: TCP throttling
From: Al Boldi @ 2005-09-20  3:54 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: linux-net, netdev
In-Reply-To: <20050919112008.17ad14f5@dxpl.pdx.osdl.net>

Stephen Hemminger wrote:
> You probably need to increase the maximum socket buffer
> sizes.  Linux defaults are conservative to avoid running
> servers out of memory.
>
> http://www.psc.edu/networking/projects/tcptune/#Linux

Thanks for the great link! It kept me up all night.

I managed to crash the server running out of memory.  Don't ask what numbers 
I used, I just went overboard.  I played with these numbers before, but 
never imagined that their scale would be in the millions.

Could you suggest sane values for 2.4/2.6 on a 100mbit link?

Thanks!

--
Al


^ permalink raw reply

* Re: ieee80211 updates
From: Matt Domsch @ 2005-09-19 22:00 UTC (permalink / raw)
  To: Jeff Garzik
  Cc: Michael Wu, Christoph Hellwig, James Ketrenos, NetDev,
	ieee80211-devel, Andrew Morton, Linux Kernel
In-Reply-To: <432E4F7A.9040605@pobox.com>

On Mon, Sep 19, 2005 at 01:41:14AM -0400, Jeff Garzik wrote:
> Michael Wu wrote:
> >If it has a version, then only the maintainer can submit patches - 
> 
> False.  Presence of an optional label in source code files does not 
> change the fundamental rules of open source, or the processes 
> surrounding patch merging in the Linux kernel.  Anybody who feels the 
> version number should be changed is welcome to submit a patch.  And a 
> reviewer along the line is welcome to reject such a patch, if they think 
> it is unwarranted.
> 
> >otherwise the
> >version is useless for identifying what code you're running. (unless other
> 
> False.  We have plenty of examples of slower-moving drivers where 
> community consensus often dictates a version number change.


This is also the reason for the 'srcversion' field available in
modinfo.  This is a CRC across the source code for a given module (not
counting #include<*>, but counting #include "*").  The version field
may not change, but if anything really cares about a particular source
code copy, and that it hasn't been patched, but the version field not
updated, they can see that.

Thanks to Rusty for implementing this.

Thanks,
Matt

-- 
Matt Domsch
Software Architect
Dell Linux Solutions linux.dell.com & www.dell.com/linux
Linux on Dell mailing lists @ http://lists.us.dell.com

^ permalink raw reply

* Re: [PATCH, netfilter] NUMA aware ipv4/netfilter/ip_tables.c
From: Eric Dumazet @ 2005-09-19 19:09 UTC (permalink / raw)
  To: Andi Kleen; +Cc: Eric dumazet, netdev, netfilter-devel
In-Reply-To: <200509191948.55333.ak@suse.de>

Andi Kleen a écrit :
> On Monday 19 September 2005 19:09, Eric dumazet wrote:
> 
>>Hi
>>
>>Part of the performance problem we have with netfilter  is memory
>>allocation is not NUMA aware, but 'only' SMP aware.
> 
> 
> How do you know? Did you measure it somehow? 

Well, it seems that even a 1MB cache is not enough for this workload, on a 
dual Opterons 275 machine.

CPU: AMD64 processors, speed 2205.54 MHz (estimated)
Counted DATA_CACHE_MISSES events (Data cache misses) with a unit mask of 0x00 
(No unit mask) count 5000
samples  %        symbol name
86104    13.3027  ipt_do_table
21508     3.3229  copy_user_generic_c
18618     2.8764  try_to_wake_up
18180     2.8087  memset
18085     2.7941  tcp_v4_rcv
16949     2.6185  schedule

# iptables -nvL | wc -l
     190



> 
> Normally I would expect fire wall state to mostly fit 
> into caches (1MB+) of modern Opterons and other NUMA systems.
> 
> 
>>What do you think of this patch ?
>>
>>Note : The allocation function is quite complex (copied from
>>drivers/pci/pci-driver.c pci_call_probe())
>>because current kernel doesnt have a NUMA aware vmalloc() wrapper
> 
> 
> Normal vmalloc is NUMA aware and allocates on the local node.
> Like all memory allocations

Yes, but I want to allocate percpu (and per node) data, using vmalloc(), not 
memory on the local node.

> 
> 
>>, maybe 
>>a future kernel will export
>>such a common function ?
> 
> 
> BTW if you want to put data onto a specific node you don't need
> to schedule there - it is enough to set the process mempolicy
> with sys_set_mempolicy. This is fine from kernel too, as long
> as you save/restore the old one (current->mempolicy) 

OK thanks, I will try this.

Eric

^ permalink raw reply

* Re: TCP throttling
From: Stephen Hemminger @ 2005-09-19 18:20 UTC (permalink / raw)
  To: Al Boldi; +Cc: linux-net, netdev
In-Reply-To: <200509190646.57579.a1426z@gawab.com>

You probably need to increase the maximum socket buffer
sizes.  Linux defaults are conservative to avoid running
servers out of memory.

http://www.psc.edu/networking/projects/tcptune/#Linux

^ permalink raw reply

* Re: [PATCH, netfilter] NUMA aware ipv4/netfilter/ip_tables.c
From: Andi Kleen @ 2005-09-19 17:48 UTC (permalink / raw)
  To: Eric dumazet; +Cc: netdev, netfilter-devel
In-Reply-To: <432EF0C5.5090908@cosmosbay.com>

On Monday 19 September 2005 19:09, Eric dumazet wrote:
> Hi
>
> Part of the performance problem we have with netfilter  is memory
> allocation is not NUMA aware, but 'only' SMP aware.

How do you know? Did you measure it somehow? 

Normally I would expect fire wall state to mostly fit 
into caches (1MB+) of modern Opterons and other NUMA systems.

> What do you think of this patch ?
>
> Note : The allocation function is quite complex (copied from
> drivers/pci/pci-driver.c pci_call_probe())
> because current kernel doesnt have a NUMA aware vmalloc() wrapper

Normal vmalloc is NUMA aware and allocates on the local node.
Like all memory allocations

> , maybe 
> a future kernel will export
> such a common function ?

BTW if you want to put data onto a specific node you don't need
to schedule there - it is enough to set the process mempolicy
with sys_set_mempolicy. This is fine from kernel too, as long
as you save/restore the old one (current->mempolicy) 

-Andi


>

^ permalink raw reply

* Re: workaround large MTU and N-order allocation failures
From: Ganesh Venkatesan @ 2005-09-19 17:25 UTC (permalink / raw)
  To: Dan Aloni; +Cc: Francois Romieu, Linux Kernel List, netdev, Nick Piggin
In-Reply-To: <20050919071358.GA7107@localdomain>

82546GB supports an incoming Rx packet to be received in multiple rx
buffers. A driver that enables this feature is under test currently.
What version of the e1000 are you using?

ganesh.

On 9/19/05, Dan Aloni <da-x@monatomic.org> wrote:
> On Mon, Sep 19, 2005 at 01:08:22AM +0200, Francois Romieu wrote:
> > Dan Aloni <da-x@monatomic.org> :
> > [...]
> > > The problem with large MTU is external memory fragmentation in
> > > the buddy system following high workload, causing alloc_skb() to
> > > fail.
> >
> > If the issue hits the Rx path, it is probably the responsibility of
> > the device driver. Which kind of hardware do you use ?
> 
> We are using a SuperMicro board and the network driver is e1000. The
> revision of the chipset is 82546GB-copper (maps to e1000_82546_rev_3).
> 
> This particular chipset does not support packet splitting, so we
> are looking for a hack on the skb layer.
> 
> --
> Dan Aloni
> da-x@monatomic.org, da-x@colinux.org, da-x@gmx.net
> -
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply

* Re: [PATCH, netfilter] NUMA aware ipv4/netfilter/ip_tables.c
From: Eric Dumazet @ 2005-09-19 17:20 UTC (permalink / raw)
  To: netfilter-devel; +Cc: netdev
In-Reply-To: <432EF0C5.5090908@cosmosbay.com>

Eric dumazet a écrit :
> Hi
> 
> Part of the performance problem we have with netfilter  is memory 
> allocation is not NUMA aware, but 'only' SMP aware.
> 
> What do you think of this patch ?
> 

...

> +#ifdef CONFIG_NUMA
> +		set_cpus_allowed(current, oldmask);
> +		mpol_free(current->mempolicy);
> +		current->mempolicy = oldpol;
> +#endif
> +		if (newinfo->entries[cpu] == 0) {
> +			free_table_info(newinfo);
> +			return NULL;
> +		if (!newinfo->entry0)
> +			newinfo->entry0 = newinfo->entries[cpu];
> +		}   // ERROR
> +	}
> +	return newinfo;
> +}
> +

Oops sorry for this misplaced brace. It should be :

 > +#ifdef CONFIG_NUMA
 > +		set_cpus_allowed(current, oldmask);
 > +		mpol_free(current->mempolicy);
 > +		current->mempolicy = oldpol;
 > +#endif
 > +		if (newinfo->entries[cpu] == 0) {
 > +			free_table_info(newinfo);
 > +			return NULL;
 > +             } // HERE
 > +		if (!newinfo->entry0)
 > +			newinfo->entry0 = newinfo->entries[cpu];
 > +	}
 > +	return newinfo;
 > +}
 > +

^ permalink raw reply

* [PATCH, netfilter] NUMA aware ipv4/netfilter/ip_tables.c
From: Eric dumazet @ 2005-09-19 17:09 UTC (permalink / raw)
  To: netfilter-devel; +Cc: netdev

[-- Attachment #1: Type: text/plain, Size: 455 bytes --]

Hi

Part of the performance problem we have with netfilter  is memory 
allocation is not NUMA aware, but 'only' SMP aware.

What do you think of this patch ?

Note : The allocation function is quite complex (copied from 
drivers/pci/pci-driver.c pci_call_probe())
because current kernel doesnt have a NUMA aware vmalloc() wrapper, maybe 
a future kernel will export
such a common function ?

Thank you

Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>



[-- Attachment #2: patch_ip_tables_numa --]
[-- Type: text/plain, Size: 9518 bytes --]

--- linux-2.6.14-rc1.p1/net/ipv4/netfilter/ip_tables.c	2005-09-19 19:56:12.000000000 +0200
+++ linux-2.6.14-rc1/net/ipv4/netfilter/ip_tables.c	2005-09-19 21:03:44.000000000 +0200
@@ -17,6 +17,7 @@
 #include <linux/skbuff.h>
 #include <linux/kmod.h>
 #include <linux/vmalloc.h>
+#include <linux/mempolicy.h>
 #include <linux/netdevice.h>
 #include <linux/module.h>
 #include <linux/tcp.h>
@@ -82,11 +83,6 @@
    context stops packets coming through and allows user context to read
    the counters or update the rules.
 
-   To be cache friendly on SMP, we arrange them like so:
-   [ n-entries ]
-   ... cache-align padding ...
-   [ n-entries ]
-
    Hence the start of any table is given by get_table() below.  */
 
 /* The table itself */
@@ -104,7 +100,8 @@
 	unsigned int underflow[NF_IP_NUMHOOKS];
 
 	/* ipt_entry tables: one per CPU */
-	char entries[0] ____cacheline_aligned;
+	void *entry0 ; /* entry for the first possible cpu */
+	void *entries[NR_CPUS];
 };
 
 static LIST_HEAD(ipt_target);
@@ -112,11 +109,6 @@
 static LIST_HEAD(ipt_tables);
 #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0)
 
-#ifdef CONFIG_SMP
-#define TABLE_OFFSET(t,p) (SMP_ALIGN((t)->size)*(p))
-#else
-#define TABLE_OFFSET(t,p) 0
-#endif
 
 #if 0
 #define down(x) do { printk("DOWN:%u:" #x "\n", __LINE__); down(x); } while(0)
@@ -289,8 +281,7 @@
 
 	read_lock_bh(&table->lock);
 	IP_NF_ASSERT(table->valid_hooks & (1 << hook));
-	table_base = (void *)table->private->entries
-		+ TABLE_OFFSET(table->private, smp_processor_id());
+	table_base = (void *)table->private->entries[smp_processor_id()];
 	e = get_entry(table_base, table->private->hook_entry[hook]);
 
 #ifdef CONFIG_NETFILTER_DEBUG
@@ -571,7 +562,7 @@
 	for (hook = 0; hook < NF_IP_NUMHOOKS; hook++) {
 		unsigned int pos = newinfo->hook_entry[hook];
 		struct ipt_entry *e
-			= (struct ipt_entry *)(newinfo->entries + pos);
+			= (struct ipt_entry *)(newinfo->entry0 + pos);
 
 		if (!(valid_hooks & (1 << hook)))
 			continue;
@@ -621,13 +612,13 @@
 						goto next;
 
 					e = (struct ipt_entry *)
-						(newinfo->entries + pos);
+						(newinfo->entry0 + pos);
 				} while (oldpos == pos + e->next_offset);
 
 				/* Move along one */
 				size = e->next_offset;
 				e = (struct ipt_entry *)
-					(newinfo->entries + pos + size);
+					(newinfo->entry0 + pos + size);
 				e->counters.pcnt = pos;
 				pos += size;
 			} else {
@@ -644,7 +635,7 @@
 					newpos = pos + e->next_offset;
 				}
 				e = (struct ipt_entry *)
-					(newinfo->entries + newpos);
+					(newinfo->entry0 + newpos);
 				e->counters.pcnt = pos;
 				pos = newpos;
 			}
@@ -874,11 +865,11 @@
 	duprintf("translate_table: size %u\n", newinfo->size);
 	i = 0;
 	/* Walk through entries, checking offsets. */
-	ret = IPT_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+	ret = IPT_ENTRY_ITERATE(newinfo->entry0, newinfo->size,
 				check_entry_size_and_hooks,
 				newinfo,
-				newinfo->entries,
-				newinfo->entries + size,
+				newinfo->entry0,
+				newinfo->entry0 + size,
 				hook_entries, underflows, &i);
 	if (ret != 0)
 		return ret;
@@ -911,20 +902,21 @@
 
 	/* Finally, each sanity check must pass */
 	i = 0;
-	ret = IPT_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+	ret = IPT_ENTRY_ITERATE(newinfo->entry0, newinfo->size,
 				check_entry, name, size, &i);
 
 	if (ret != 0) {
-		IPT_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+		IPT_ENTRY_ITERATE(newinfo->entry0, newinfo->size,
 				  cleanup_entry, &i);
 		return ret;
 	}
 
 	/* And one copy for every other CPU */
-	for (i = 1; i < num_possible_cpus(); i++) {
-		memcpy(newinfo->entries + SMP_ALIGN(newinfo->size)*i,
-		       newinfo->entries,
-		       SMP_ALIGN(newinfo->size));
+	for_each_cpu(i) {
+		if (newinfo->entries[i] != newinfo->entry0)
+			memcpy(newinfo->entries[i],
+				newinfo->entry0,
+				newinfo->size);
 	}
 
 	return ret;
@@ -940,15 +932,12 @@
 
 #ifdef CONFIG_NETFILTER_DEBUG
 	{
-		struct ipt_entry *table_base;
-		unsigned int i;
-
-		for (i = 0; i < num_possible_cpus(); i++) {
-			table_base =
-				(void *)newinfo->entries
-				+ TABLE_OFFSET(newinfo, i);
+		int cpu;
 
-			table_base->comefrom = 0xdead57ac;
+		for_each_cpu(cpu) {
+			struct ipt_entry *table_base = newinfo->entries[cpu];
+			if (table_base)
+				table_base->comefrom = 0xdead57ac;
 		}
 	}
 #endif
@@ -990,9 +979,9 @@
 	unsigned int cpu;
 	unsigned int i;
 
-	for (cpu = 0; cpu < num_possible_cpus(); cpu++) {
+	for_each_cpu(cpu) {
 		i = 0;
-		IPT_ENTRY_ITERATE(t->entries + TABLE_OFFSET(t, cpu),
+		IPT_ENTRY_ITERATE(t->entries[cpu],
 				  t->size,
 				  add_entry_to_counter,
 				  counters,
@@ -1026,7 +1015,7 @@
 	write_unlock_bh(&table->lock);
 
 	/* ... then copy entire thing from CPU 0... */
-	if (copy_to_user(userptr, table->private->entries, total_size) != 0) {
+	if (copy_to_user(userptr, table->private->entry0, total_size) != 0) {
 		ret = -EFAULT;
 		goto free_counters;
 	}
@@ -1038,7 +1027,7 @@
 		struct ipt_entry_match *m;
 		struct ipt_entry_target *t;
 
-		e = (struct ipt_entry *)(table->private->entries + off);
+		e = (struct ipt_entry *)(table->private->entry0 + off);
 		if (copy_to_user(userptr + off
 				 + offsetof(struct ipt_entry, counters),
 				 &counters[num],
@@ -1107,6 +1096,51 @@
 	return ret;
 }
 
+static void free_table_info(struct ipt_table_info *info)
+{
+	int cpu;
+	for_each_cpu(cpu)
+		vfree(info->entries[cpu]);
+	kfree(info);
+}
+
+static struct ipt_table_info *alloc_table_info(unsigned int size)
+{
+struct ipt_table_info *newinfo;
+int cpu;
+	newinfo = kmalloc(sizeof(struct ipt_table_info), GFP_KERNEL);
+	if (!newinfo)
+		return NULL;
+	memset(newinfo, 0, sizeof(*newinfo));
+	for_each_cpu(cpu) {
+#ifdef CONFIG_NUMA
+		struct mempolicy *oldpol;
+		cpumask_t oldmask = current->cpus_allowed;
+		int node = cpu_to_node(cpu);
+		if (node >= 0 && node_online(node))
+		    set_cpus_allowed(current, node_to_cpumask(node));
+		/* And set default memory allocation policy */
+		oldpol = current->mempolicy;
+		current->mempolicy = &default_policy;
+		mpol_get(current->mempolicy);
+#endif
+		newinfo->entries[cpu] = vmalloc(size);
+#ifdef CONFIG_NUMA
+		set_cpus_allowed(current, oldmask);
+		mpol_free(current->mempolicy);
+		current->mempolicy = oldpol;
+#endif
+		if (newinfo->entries[cpu] == 0) {
+			free_table_info(newinfo);
+			return NULL;
+		if (!newinfo->entry0)
+			newinfo->entry0 = newinfo->entries[cpu];
+		}
+	}
+	return newinfo;
+}
+
+
 static int
 do_replace(void __user *user, unsigned int len)
 {
@@ -1127,12 +1161,10 @@
 	if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages)
 		return -ENOMEM;
 
-	newinfo = vmalloc(sizeof(struct ipt_table_info)
-			  + SMP_ALIGN(tmp.size) * num_possible_cpus());
+	newinfo = alloc_table_info(tmp.size);
 	if (!newinfo)
 		return -ENOMEM;
-
-	if (copy_from_user(newinfo->entries, user + sizeof(tmp),
+	if (copy_from_user(newinfo->entry0, user + sizeof(tmp),
 			   tmp.size) != 0) {
 		ret = -EFAULT;
 		goto free_newinfo;
@@ -1185,8 +1217,8 @@
 	/* Get the old counters. */
 	get_counters(oldinfo, counters);
 	/* Decrease module usage counts and free resource */
-	IPT_ENTRY_ITERATE(oldinfo->entries, oldinfo->size, cleanup_entry,NULL);
-	vfree(oldinfo);
+	IPT_ENTRY_ITERATE(oldinfo->entry0, oldinfo->size, cleanup_entry,NULL);
+	free_table_info(oldinfo);
 	if (copy_to_user(tmp.counters, counters,
 			 sizeof(struct ipt_counters) * tmp.num_counters) != 0)
 		ret = -EFAULT;
@@ -1198,11 +1230,11 @@
 	module_put(t->me);
 	up(&ipt_mutex);
  free_newinfo_counters_untrans:
-	IPT_ENTRY_ITERATE(newinfo->entries, newinfo->size, cleanup_entry,NULL);
+	IPT_ENTRY_ITERATE(newinfo->entry0, newinfo->size, cleanup_entry,NULL);
  free_newinfo_counters:
 	vfree(counters);
  free_newinfo:
-	vfree(newinfo);
+	free_table_info(newinfo);
 	return ret;
 }
 
@@ -1264,7 +1296,7 @@
 	}
 
 	i = 0;
-	IPT_ENTRY_ITERATE(t->private->entries,
+	IPT_ENTRY_ITERATE(t->private->entry0,
 			  t->private->size,
 			  add_counter_to_entry,
 			  paddc->counters,
@@ -1454,15 +1486,20 @@
 {
 	int ret;
 	struct ipt_table_info *newinfo;
-	static struct ipt_table_info bootstrap
-		= { 0, 0, 0, { 0 }, { 0 }, { } };
+	static struct ipt_table_info bootstrap = {
+		.size = 0,
+		.number = 0,
+		.initial_entries = 0,
+		.hook_entry = { 0 },
+		.underflow = { 0 },
+		.entry0 = NULL,
+		.entries = {NULL }
+		};
 
-	newinfo = vmalloc(sizeof(struct ipt_table_info)
-			  + SMP_ALIGN(repl->size) * num_possible_cpus());
+	newinfo = alloc_table_info(repl->size);
 	if (!newinfo)
 		return -ENOMEM;
-
-	memcpy(newinfo->entries, repl->entries, repl->size);
+	memcpy(newinfo->entry0, repl->entries, repl->size);
 
 	ret = translate_table(table->name, table->valid_hooks,
 			      newinfo, repl->size,
@@ -1470,13 +1507,13 @@
 			      repl->hook_entry,
 			      repl->underflow);
 	if (ret != 0) {
-		vfree(newinfo);
+		free_table_info(newinfo);
 		return ret;
 	}
 
 	ret = down_interruptible(&ipt_mutex);
 	if (ret != 0) {
-		vfree(newinfo);
+		free_table_info(newinfo);
 		return ret;
 	}
 
@@ -1505,7 +1542,7 @@
 	return ret;
 
  free_unlock:
-	vfree(newinfo);
+	free_table_info(newinfo);
 	goto unlock;
 }
 
@@ -1516,9 +1553,9 @@
 	up(&ipt_mutex);
 
 	/* Decrease module usage counts and free resources */
-	IPT_ENTRY_ITERATE(table->private->entries, table->private->size,
+	IPT_ENTRY_ITERATE(table->private->entry0, table->private->size,
 			  cleanup_entry, NULL);
-	vfree(table->private);
+	free_table_info(table->private);
 }
 
 /* Returns 1 if the port is matched by the range, 0 otherwise */

^ permalink raw reply

* Re: workaround large MTU and N-order allocation failures
From: Al Boldi @ 2005-09-19 13:38 UTC (permalink / raw)
  To: netdev; +Cc: lkml
In-Reply-To: <1127111462.5272.7.camel@npiggin-nld.site>

Nick Piggin wrote:
> On Sun, 2005-09-18 at 17:35 +0300, Dan Aloni wrote:
> > Hello,
> >
> > Is there currently a workaround available for handling large MTU
> > (larger than 1 page, even 2-order) in the Linux network stack?
> >
> > The problem with large MTU is external memory fragmentation in
> > the buddy system following high workload, causing alloc_skb() to
> > fail.
> >
> > I'm interested in patches for both 2.4 and 2.6 kernels.
>
> Yes there is currently a workaround. That is to keep increasing
> /proc/sys/vm/min_free_kbytes until your allocation failures stop.

How do you do it in 2.4?

--
Al

^ permalink raw reply

* 素人流失ライブラリー
From: 無修正動画 @ 2005-09-19  8:59 UTC (permalink / raw)
  To: netdev


海外サーバならではの完全無修正動画!!

渋谷の棒デパートエレベーター嬢流失動画
http://puntreturn.com/hd/?50720190458024174

フェ○ス女子大学生の部室内SEX戦慄の隠し撮り!!
http://puntreturn.com/gf/?50720190458024174

^ permalink raw reply

* Re: workaround large MTU and N-order allocation failures
From: Dan Aloni @ 2005-09-19  7:13 UTC (permalink / raw)
  To: Francois Romieu; +Cc: Linux Kernel List, netdev, Nick Piggin
In-Reply-To: <20050918230822.GA5440@electric-eye.fr.zoreil.com>

On Mon, Sep 19, 2005 at 01:08:22AM +0200, Francois Romieu wrote:
> Dan Aloni <da-x@monatomic.org> :
> [...]
> > The problem with large MTU is external memory fragmentation in
> > the buddy system following high workload, causing alloc_skb() to 
> > fail.
> 
> If the issue hits the Rx path, it is probably the responsibility of
> the device driver. Which kind of hardware do you use ?

We are using a SuperMicro board and the network driver is e1000. The
revision of the chipset is 82546GB-copper (maps to e1000_82546_rev_3).

This particular chipset does not support packet splitting, so we
are looking for a hack on the skb layer.

-- 
Dan Aloni
da-x@monatomic.org, da-x@colinux.org, da-x@gmx.net

^ permalink raw reply

* Re: workaround large MTU and N-order allocation failures
From: Nick Piggin @ 2005-09-19  6:31 UTC (permalink / raw)
  To: Dan Aloni; +Cc: lkml, netdev
In-Reply-To: <20050918143526.GA24181@localdomain>

On Sun, 2005-09-18 at 17:35 +0300, Dan Aloni wrote:
> Hello,
> 
> Is there currently a workaround available for handling large MTU 
> (larger than 1 page, even 2-order) in the Linux network stack?
> 
> The problem with large MTU is external memory fragmentation in
> the buddy system following high workload, causing alloc_skb() to 
> fail.
> 
> I'm interested in patches for both 2.4 and 2.6 kernels.
> 

Yes there is currently a workaround. That is to keep increasing
/proc/sys/vm/min_free_kbytes until your allocation failures stop.

Nick

-- 
SUSE Labs, Novell Inc.



Send instant messages to your online friends http://au.messenger.yahoo.com 

^ permalink raw reply

* ieee80211 updates
From: Jeff Garzik @ 2005-09-19  5:41 UTC (permalink / raw)
  To: Michael Wu
  Cc: Christoph Hellwig, James Ketrenos, NetDev, ieee80211-devel,
	Andrew Morton, Linux Kernel
In-Reply-To: <20050919004450.16m2d1hn7les0o00@www.sourmilk.net>

Michael Wu wrote:
> If it has a version, then only the maintainer can submit patches - 

False.  Presence of an optional label in source code files does not 
change the fundamental rules of open source, or the processes 
surrounding patch merging in the Linux kernel.  Anybody who feels the 
version number should be changed is welcome to submit a patch.  And a 
reviewer along the line is welcome to reject such a patch, if they think 
it is unwarranted.


> otherwise the
> version is useless for identifying what code you're running. (unless other

False.  We have plenty of examples of slower-moving drivers where 
community consensus often dictates a version number change.


> submitters decide to alter the version too, which is probably not a good 
> idea)

For any given driver/subsystem/whatever version number in the kernel, 
ultimately a submittor changes the version and one or more reviewers 
approve this, by pulling the change into their tree.  Your "probably not 
a good idea" is the 100% case here, including the master version number 
in ./Makefile.


>>> That early and often thing is true for drivers aswell, the intel 
>>> wireless
>>> driver are so hopelessly out of date in mainline just after 
>>> submission that
>>> it's not funny anymore.  Hopefully we'll have a mainline maintainer for
>>> them soon that imports everything important from intel and other 
>>> contributors.
>>
>>
>> Patience:  We still have over 20 patches to merge, before even getting
>> to the ipw updates.
>>
> I wish those patches were submitted and merged quickly when they were 
> created
> instead of piling up. Other people can't get patches merged because it 

Agreed.


> Other people can't get patches merged because it
> would
> break the chain of patches. Patches are being sent too late and 
> and infrequently.. 

Patience.  We've got to balance kernel hackers' insatiable desire for 
cleanups, with the desire of users and driver developers to move forward 
with Linux wireless support.

Since Intel has useful stuff, stuff which affects a wide range of 
hardware owned by Linux users, it's worth waiting a bit to let them 
catch up.  Of course, if it takes forever to merge their stuff, someone 
else will inevitably come along and speed up the process.  Open source 
at work.

Currently, it has rather been like a clock algorithm:  merge initial 
ieee80211 code from Intel.  Accept months worth of cleanups from 
community.  Accept unifying updates from Jouni.  Begin merging work from 
Jiri and SuSE.  Now the clock hand points at Intel again, and they've 
been waiting a while to send useful stuff.

People are slowly converging at a decent solution, while at the same 
moving wireless hardware support forward.  The need to improve the 
wireless API is balanced with the need to keep wireless hardware working 
(and/or enable new wireless hardware).

This convergence will be attained more rapidly once the community starts 
WORKING TOGETHER, rather than sending me competing patches.  Person A 
breaks Person B's work.  And then back again.

	Jeff

^ permalink raw reply

* TCP throttling
From: Al Boldi @ 2005-09-19  3:53 UTC (permalink / raw)
  To: linux-net; +Cc: netdev


Is there a way to tune the throttling nature of a TCP connection?

i.e:
One TCP connection is slower than two over the same bandwidth limited link.
Can this one TCP connection be tuned to make full use of the link-bandwidth?

Thanks!

--
Al


^ permalink raw reply

* Re: workaround large MTU and N-order allocation failures
From: Francois Romieu @ 2005-09-18 23:08 UTC (permalink / raw)
  To: Dan Aloni; +Cc: Linux Kernel List, netdev, Nick Piggin
In-Reply-To: <20050918143526.GA24181@localdomain>

Dan Aloni <da-x@monatomic.org> :
[...]
> The problem with large MTU is external memory fragmentation in
> the buddy system following high workload, causing alloc_skb() to 
> fail.

If the issue hits the Rx path, it is probably the responsibility of
the device driver. Which kind of hardware do you use ?

--
Ueimor

^ permalink raw reply

* [PATCH,CFT] forcedeth: Remove superflous rx engine stop/start cycles.
From: Manfred Spraul @ 2005-09-18 14:37 UTC (permalink / raw)
  To: Netdev; +Cc: Ayaz Abdulla

[-- Attachment #1: Type: text/plain, Size: 268 bytes --]

Hi all,

Ayaz noticed that forcedeth stops and restarts the rx engine every 3 
seconds (link timeout). The attached patch fixes that.
It also contains a larger whitespace cleanup: I've replaced a few spaces 
in the comments with tabs.

Please test it.

--
    Manfred

[-- Attachment #2: patch-forcedeth-045-start_stop_rx --]
[-- Type: text/plain, Size: 2961 bytes --]

--- 2.6/drivers/net/forcedeth.c	2005-09-18 16:21:44.000000000 +0200
+++ build-2.6/drivers/net/forcedeth.c	2005-09-18 16:22:42.000000000 +0200
@@ -80,7 +80,7 @@
  *			   into nv_close, otherwise reenabling for wol can
  *			   cause DMA to kfree'd memory.
  *	0.31: 14 Nov 2004: ethtool support for getting/setting link
- *	                   capabilities.
+ *			   capabilities.
  *	0.32: 16 Apr 2005: RX_ERROR4 handling added.
  *	0.33: 16 May 2005: Support for MCP51 added.
  *	0.34: 18 Jun 2005: Add DEV_NEED_LINKTIMER to all nForce nics.
@@ -89,14 +89,15 @@
  *	0.37: 10 Jul 2005: Additional ethtool support, cleanup of pci id list
  *	0.38: 16 Jul 2005: tx irq rewrite: Use global flags instead of
  *			   per-packet flags.
- *      0.39: 18 Jul 2005: Add 64bit descriptor support.
- *      0.40: 19 Jul 2005: Add support for mac address change.
- *      0.41: 30 Jul 2005: Write back original MAC in nv_close instead
+ *	0.39: 18 Jul 2005: Add 64bit descriptor support.
+ *	0.40: 19 Jul 2005: Add support for mac address change.
+ *	0.41: 30 Jul 2005: Write back original MAC in nv_close instead
  *			   of nv_remove
- *      0.42: 06 Aug 2005: Fix lack of link speed initialization
+ *	0.42: 06 Aug 2005: Fix lack of link speed initialization
  *			   in the second (and later) nv_open call
- *      0.43: 10 Aug 2005: Add support for tx checksum.
- *      0.44: 20 Aug 2005: Add support for scatter gather and segmentation.
+ *	0.43: 10 Aug 2005: Add support for tx checksum.
+ *	0.44: 20 Aug 2005: Add support for scatter gather and segmentation.
+ *	0.45: 18 Sep 2005: Remove nv_stop/start_rx from every link check
  *
  * Known bugs:
  * We suspect that on some hardware no TX done interrupts are generated.
@@ -108,7 +109,7 @@
  * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
  * superfluous timer interrupts from the nic.
  */
-#define FORCEDETH_VERSION		"0.44"
+#define FORCEDETH_VERSION		"0.45"
 #define DRV_NAME			"forcedeth"
 
 #include <linux/module.h>
@@ -1613,6 +1614,17 @@
 	spin_unlock_irq(&np->lock);
 }
 
+/**
+ * nv_update_linkspeed: Setup the MAC according to the link partner
+ * @dev: Network device to be configured
+ *
+ * The function queries the PHY and checks if there is a link partner.
+ * If yes, then it sets up the MAC accordingly. Otherwise, the MAC is
+ * set to 10 MBit HD.
+ *
+ * The function returns 0 if there is no link partner and 1 if there is
+ * a good link partner.
+ */
 static int nv_update_linkspeed(struct net_device *dev)
 {
 	struct fe_priv *np = get_nvpriv(dev);
@@ -1752,13 +1764,11 @@
 static void nv_linkchange(struct net_device *dev)
 {
 	if (nv_update_linkspeed(dev)) {
-		if (netif_carrier_ok(dev)) {
-			nv_stop_rx(dev);
-		} else {
+		if (!netif_carrier_ok(dev)) {
 			netif_carrier_on(dev);
 			printk(KERN_INFO "%s: link up.\n", dev->name);
+			nv_start_rx(dev);
 		}
-		nv_start_rx(dev);
 	} else {
 		if (netif_carrier_ok(dev)) {
 			netif_carrier_off(dev);

^ permalink raw reply

* workaround large MTU and N-order allocation failures
From: Dan Aloni @ 2005-09-18 14:35 UTC (permalink / raw)
  To: Linux Kernel List, netdev; +Cc: Nick Piggin

Hello,

Is there currently a workaround available for handling large MTU 
(larger than 1 page, even 2-order) in the Linux network stack?

The problem with large MTU is external memory fragmentation in
the buddy system following high workload, causing alloc_skb() to 
fail.

I'm interested in patches for both 2.4 and 2.6 kernels.

Thanks,

-- 
Dan Aloni
da-x@monatomic.org, da-x@colinux.org, da-x@gmx.net

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox