Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 9 Mar 2013 13:14:16 +0100
From:      =?ISO-8859-1?Q?Ermal_Lu=E7i?= <eri@freebsd.org>
To:        Kajetan Staszkiewicz <vegeta@tuxpowered.net>
Cc:        "freebsd-net@freebsd.org" <freebsd-net@freebsd.org>, "freebsd-pf@freebsd.org" <freebsd-pf@freebsd.org>
Subject:   Re: [patch] Source entries removing is awfully slow.
Message-ID:  <CAPBZQG0Jj_c-XvVJNV2S02xcitr%2Bnhs%2BmV=GjJm3YeM6iPUX7g@mail.gmail.com>
In-Reply-To: <201303082151.00895.vegeta@tuxpowered.net>
References:  <201303081419.17743.vegeta@tuxpowered.net> <CAPBZQG2bb2xzPB2UoPUDx-ifyBdmjac6b8kV76DTPBUzLCDmJw@mail.gmail.com> <201303082151.00895.vegeta@tuxpowered.net>

next in thread | previous in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]
On Fri, Mar 8, 2013 at 9:51 PM, Kajetan Staszkiewicz
<vegeta@tuxpowered.net>wrote:

> Dnia pi±tek, 8 marca 2013 o 21:11:43 Ermal Luçi napisa³(a):
> > Is this FreeBSD 9.x or HEAD?
>
> I found the problem and developed the patch on 9.1.
>
> Can you please test this more 'beautiful' patch.
Its similar to yours but also delays src state removal to the proper purge
thread.

Though the src node removal option through pfctl -K does a lot of job to
cleanup things
Still need to undertand why it takes so much time for you to loop through
500K states.
The purge thread does that every tick by partitioning it to a few per time
slot but still minutes is way loong.

Can you please try to give a top -SH view of the time when this happens and
a pfctl -vvsa output?



> --
> | pozdrawiam / greetings | powered by Debian, CentOS and FreeBSD |
> |  Kajetan Staszkiewicz  | jabber,email: vegeta()tuxpowered net  |
> |        Vegeta          | www: http://vegeta.tuxpowered.net     |
> `------------------------^---------------------------------------'
>



-- 
Ermal

[-- Attachment #2 --]
diff --git a/sys/contrib/pf/net/pf.c b/sys/contrib/pf/net/pf.c
index 9fb05ae..4df40cc 100644
--- a/sys/contrib/pf/net/pf.c
+++ b/sys/contrib/pf/net/pf.c
@@ -720,6 +720,9 @@ pf_insert_src_node(struct pf_src_node **sn, struct pf_rule *rule,
 		    rule->max_src_conn_rate.limit,
 		    rule->max_src_conn_rate.seconds);
 
+#ifdef __FreeBSD__
+		TAILQ_INIT(&(*sn)->state_list);
+#endif
 		(*sn)->af = af;
 		if (rule->rule_flag & PFRULE_RULESRCTRACK ||
 		    rule->rpool.opts & PF_POOL_STICKYADDR)
@@ -1453,6 +1456,9 @@ pf_purge_expired_src_nodes(int waslocked)
 #endif
 {
 	struct pf_src_node		*cur, *next;
+#ifdef __FreeBSD__
+	struct pf_state			*s;
+#endif
 	int				 locked = waslocked;
 
 #ifdef __FreeBSD__
@@ -1486,6 +1492,12 @@ pf_purge_expired_src_nodes(int waslocked)
 					pf_rm_rule(NULL, cur->rule.ptr);
 			}
 #ifdef __FreeBSD__
+			while (!TAILQ_EMPTY(&cur->state_list)) {
+				s = TAILQ_FIRST(&cur->state_list);
+				TAILQ_REMOVE(&cur->state_list, s, srcnode_link);
+				s->src_node = NULL;
+				s->nat_src_node = NULL;
+			}
 			RB_REMOVE(pf_src_tree, &V_tree_src_tracking, cur);
 			V_pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
 			V_pf_status.src_nodes--;
@@ -1529,6 +1541,10 @@ pf_src_tree_remove_state(struct pf_state *s)
 #endif
 			s->src_node->expire = time_second + timeout;
 		}
+#ifdef __FreeBSD__
+		if (!TAILQ_EMPTY(&s->src_node->state_list))
+			TAILQ_REMOVE(&s->src_node->state_list, s, srcnode_link);
+#endif
 	}
 	if (s->nat_src_node != s->src_node && s->nat_src_node != NULL) {
 		if (--s->nat_src_node->states <= 0) {
@@ -1542,6 +1558,10 @@ pf_src_tree_remove_state(struct pf_state *s)
 #endif
 			s->nat_src_node->expire = time_second + timeout;
 		}
+#ifdef __FreeBSD__
+		if (!TAILQ_EMPTY(&s->nat_src_node->state_list))
+			TAILQ_REMOVE(&s->nat_src_node->state_list, s, srcnode_link);
+#endif
 	}
 	s->src_node = s->nat_src_node = NULL;
 }
@@ -3949,8 +3969,18 @@ pf_create_state(struct pf_rule *r, struct pf_rule *nr, struct pf_rule *a,
 		pool_put(&pf_state_pl, s);
 #endif
 		return (PF_DROP);
+#ifdef __FreeBSD__
+	} else {
+		if (sn != NULL)
+			TAILQ_INSERT_HEAD(&sn->state_list, s, srcnode_link);
+		if (nsn != NULL)
+			TAILQ_INSERT_HEAD(&nsn->state_list, s, srcnode_link);
+		*sm = s;
+	}
+#else
 	} else
 		*sm = s;
+#endif
 
 	pf_set_rt_ifp(s, pd->src);	/* needs s->state_key set */
 	if (tag > 0) {
diff --git a/sys/contrib/pf/net/pf_ioctl.c b/sys/contrib/pf/net/pf_ioctl.c
index 3b130e5..2864e9a 100644
--- a/sys/contrib/pf/net/pf_ioctl.c
+++ b/sys/contrib/pf/net/pf_ioctl.c
@@ -3789,7 +3789,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
 
 	case DIOCKILLSRCNODES: {
 		struct pf_src_node	*sn;
+#ifndef __FreeBSD__
 		struct pf_state		*s;
+#endif
 		struct pfioc_src_node_kill *psnk =
 		    (struct pfioc_src_node_kill *)addr;
 		u_int			killed = 0;
@@ -3808,6 +3810,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
 				&psnk->psnk_dst.addr.v.a.mask,
 				&sn->raddr, sn->af)) {
 				/* Handle state to src_node linkage */
+#ifndef __FreeBSD__ 
 				if (sn->states != 0) {
 					RB_FOREACH(s, pf_state_tree_id,
 #ifdef __FreeBSD__
@@ -3822,13 +3825,16 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
 					}
 					sn->states = 0;
 				}
+#endif
 				sn->expire = 1;
 				killed++;
 			}
 		}
 
+#if 0
 		if (killed > 0)
 			pf_purge_expired_src_nodes(1);
+#endif
 
 		psnk->psnk_killed = killed;
 		break;
diff --git a/sys/contrib/pf/net/pfvar.h b/sys/contrib/pf/net/pfvar.h
index dab70c5..e31d39d 100644
--- a/sys/contrib/pf/net/pfvar.h
+++ b/sys/contrib/pf/net/pfvar.h
@@ -739,6 +739,9 @@ struct pf_src_node {
 	struct pf_addr	 raddr;
 	union pf_rule_ptr rule;
 	struct pfi_kif	*kif;
+#ifdef __FreeBSD__
+	TAILQ_HEAD(, pf_state)	state_list;
+#endif
 	u_int64_t	 bytes[2];
 	u_int64_t	 packets[2];
 	u_int32_t	 states;
@@ -840,6 +843,9 @@ struct pf_state {
 
 	TAILQ_ENTRY(pf_state)	 sync_list;
 	TAILQ_ENTRY(pf_state)	 entry_list;
+#ifdef __FreeBSD__
+	TAILQ_ENTRY(pf_state)	 srcnode_link;
+#endif
 	RB_ENTRY(pf_state)	 entry_id;
 	struct pf_state_peer	 src;
 	struct pf_state_peer	 dst;

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAPBZQG0Jj_c-XvVJNV2S02xcitr%2Bnhs%2BmV=GjJm3YeM6iPUX7g>