From owner-svn-src-projects@FreeBSD.ORG  Tue May 29 19:48:35 2012
Return-Path: <owner-svn-src-projects@FreeBSD.ORG>
Delivered-To: svn-src-projects@freebsd.org
Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52])
	by hub.freebsd.org (Postfix) with ESMTP id 0575F1065672;
	Tue, 29 May 2012 19:48:35 +0000 (UTC)
	(envelope-from glebius@FreeBSD.org)
Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c])
	by mx1.freebsd.org (Postfix) with ESMTP id E4B6B8FC08;
	Tue, 29 May 2012 19:48:34 +0000 (UTC)
Received: from svn.freebsd.org (localhost [127.0.0.1])
	by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q4TJmYo0099167;
	Tue, 29 May 2012 19:48:34 GMT (envelope-from glebius@svn.freebsd.org)
Received: (from glebius@localhost)
	by svn.freebsd.org (8.14.4/8.14.4/Submit) id q4TJmYnx099163;
	Tue, 29 May 2012 19:48:34 GMT (envelope-from glebius@svn.freebsd.org)
Message-Id: <201205291948.q4TJmYnx099163@svn.freebsd.org>
From: Gleb Smirnoff <glebius@FreeBSD.org>
Date: Tue, 29 May 2012 19:48:34 +0000 (UTC)
To: src-committers@freebsd.org, svn-src-projects@freebsd.org
X-SVN-Group: projects
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Cc: 
Subject: svn commit: r236254 - projects/pf/head/sys/contrib/pf/net
X-BeenThere: svn-src-projects@freebsd.org
X-Mailman-Version: 2.1.5
Precedence: list
List-Id: "SVN commit messages for the src &quot; projects&quot;
	tree" <svn-src-projects.freebsd.org>
List-Unsubscribe: <http://lists.freebsd.org/mailman/listinfo/svn-src-projects>, 
	<mailto:svn-src-projects-request@freebsd.org?subject=unsubscribe>
List-Archive: <http://lists.freebsd.org/pipermail/svn-src-projects>
List-Post: <mailto:svn-src-projects@freebsd.org>
List-Help: <mailto:svn-src-projects-request@freebsd.org?subject=help>
List-Subscribe: <http://lists.freebsd.org/mailman/listinfo/svn-src-projects>, 
	<mailto:svn-src-projects-request@freebsd.org?subject=subscribe>
X-List-Received-Date: Tue, 29 May 2012 19:48:35 -0000

Author: glebius
Date: Tue May 29 19:48:34 2012
New Revision: 236254
URL: http://svn.freebsd.org/changeset/base/236254

Log:
  To avoid state ID collisions in multithreaded pf(4), make stateid per-cpu.

Modified:
  projects/pf/head/sys/contrib/pf/net/pf.c
  projects/pf/head/sys/contrib/pf/net/pf_ioctl.c
  projects/pf/head/sys/contrib/pf/net/pfvar.h

Modified: projects/pf/head/sys/contrib/pf/net/pf.c
==============================================================================
--- projects/pf/head/sys/contrib/pf/net/pf.c	Tue May 29 19:47:06 2012	(r236253)
+++ projects/pf/head/sys/contrib/pf/net/pf.c	Tue May 29 19:48:34 2012	(r236254)
@@ -199,6 +199,13 @@ VNET_DEFINE(uma_zone_t,	 pf_altq_z);
 
 #define	V_pf_sources_z	VNET(pf_sources_z)
 
+VNET_DEFINE(uint64_t, pf_stateid[MAXCPU]);
+#define	PFID_CPUBITS	8
+#define	PFID_CPUSHIFT	(sizeof(uint64_t) * NBBY - PFID_CPUBITS)
+#define	PFID_CPUMASK	((uint64_t)((1 << PFID_CPUBITS) - 1) <<	PFID_CPUSHIFT)
+#define	PFID_MAXID	(~PFID_CPUMASK)
+CTASSERT((1 << PFID_CPUBITS) > MAXCPU);
+
 static void		 pf_src_tree_remove_state(struct pf_state *);
 static void		 pf_init_threshold(struct pf_threshold *, u_int32_t,
 			    u_int32_t);
@@ -1020,8 +1027,11 @@ pf_state_insert(struct pfi_kif *kif, str
 		return (-1);
 
 	if (s->id == 0 && s->creatorid == 0) {
-		/* XXXGL: we need locking here */
-		s->id = htobe64(V_pf_status.stateid++);
+		/* XXX: should be atomic, but probability of collision low */
+		if ((s->id = V_pf_stateid[curcpu]++) == PFID_MAXID)
+			V_pf_stateid[curcpu] = 1;
+		s->id |= (uint64_t )curcpu << PFID_CPUSHIFT;
+		s->id = htobe64(s->id);
 		s->creatorid = V_pf_status.hostid;
 	}
 

Modified: projects/pf/head/sys/contrib/pf/net/pf_ioctl.c
==============================================================================
--- projects/pf/head/sys/contrib/pf/net/pf_ioctl.c	Tue May 29 19:47:06 2012	(r236253)
+++ projects/pf/head/sys/contrib/pf/net/pf_ioctl.c	Tue May 29 19:48:34 2012	(r236254)
@@ -71,6 +71,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/proc.h>
 #include <sys/malloc.h>
 #include <sys/kthread.h>
+#include <sys/smp.h>
 
 #include <net/if.h>
 #include <net/if_types.h>
@@ -1125,6 +1126,8 @@ pfioctl(struct cdev *dev, u_long cmd, ca
 		if (V_pf_status.running)
 			error = EEXIST;
 		else {
+			int cpu;
+
 			PF_UNLOCK();
 			error = hook_pf();
 			PF_LOCK();
@@ -1137,10 +1140,9 @@ pfioctl(struct cdev *dev, u_long cmd, ca
 			V_pf_status.running = 1;
 			V_pf_status.since = time_second;
 
-			if (V_pf_status.stateid == 0) {
-				V_pf_status.stateid = time_second;
-				V_pf_status.stateid = V_pf_status.stateid << 32;
-			}
+			CPU_FOREACH(cpu)
+				V_pf_stateid[cpu] = time_second;
+
 			DPFPRINTF(PF_DEBUG_MISC, ("pf: started\n"));
 		}
 		PF_UNLOCK();

Modified: projects/pf/head/sys/contrib/pf/net/pfvar.h
==============================================================================
--- projects/pf/head/sys/contrib/pf/net/pfvar.h	Tue May 29 19:47:06 2012	(r236253)
+++ projects/pf/head/sys/contrib/pf/net/pfvar.h	Tue May 29 19:48:34 2012	(r236254)
@@ -1336,7 +1336,6 @@ struct pf_status {
 	u_int64_t	scounters[SCNT_MAX];
 	u_int64_t	pcounters[2][2][3];
 	u_int64_t	bcounters[2][2];
-	u_int64_t	stateid;
 	u_int32_t	running;
 	u_int32_t	states;
 	u_int32_t	src_nodes;
@@ -1707,6 +1706,9 @@ VNET_DECLARE(u_long, pf_srchashmask);
 VNET_DECLARE(void *, pf_swi_cookie);
 #define V_pf_swi_cookie	VNET(pf_swi_cookie)
 
+VNET_DECLARE(uint64_t, pf_stateid[MAXCPU]);
+#define	V_pf_stateid	VNET(pf_stateid)
+
 TAILQ_HEAD(pf_altqqueue, pf_altq);
 VNET_DECLARE(struct pf_altqqueue,	 pf_altqs[2]);
 #define	V_pf_altqs			 VNET(pf_altqs)