num_possible_cpus() usage in iptables

Eric Dumazet dada1 at cosmosbay.com
Mon Oct 10 08:23:27 CEST 2005


David S. Miller a écrit :
> Guys, you can't use this interface like that.
> 
> It's a _COUNT_ of the number of possible processors, not the number of
> the higest PHYSICAL cpu index.
> 
> So you can have cpu's numbered "0" and "2", but num_possible_cpus()
> will return 2.  This is not just theoretical, Ultra60 sparc64 systems
> have this exact physical cpu numbering.   And as a result, when the
> changes went into iptables to use num_possible_cpus() instead of NR_CPUS
> it broke iptables.  It OOPS's when you load the module, in fact.
> 
> So, on such a system, this loop:
> 
> 	/* 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));
> 	}
> 
> would initialize the wrong entries.
> 
> We need to fix this.
> 
> 
Hi David

My previous patch ([PATCH 3/3] netfilter : 3 patches to boost ip_tables 
performance) addressed this problem.


http://marc.theaimsgroup.com/?l=linux-netdev&m=112733887410796&w=2

Relevant parts :

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


-		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;

But the whole thing was suspended because nobody wants to put a vmalloc_node() 
inside kernel.

Eric



More information about the netfilter-devel mailing list