svn commit: r236254 - projects/pf/head/sys/contrib/pf/net
Gleb Smirnoff
glebius at FreeBSD.org
Tue May 29 19:48:35 UTC 2012
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)
More information about the svn-src-projects
mailing list