Message ID | 1529310015-14507-2-git-send-email-yihung.wei@gmail.com |
---|---|
State | RFC |
Delegated to: | Pablo Neira |
Headers | show |
Series | netfilter: nf_conncount: optimize nf_conncount performance | expand |
On Mon, Jun 18, 2018 at 01:20:09AM -0700, Yi-Hung Wei wrote: > From: Florian Westphal <fw@strlen.de> > > We use an extra function with early exit for garbage collection. > It is not necessary to traverse the full list for every node since > it is enough to zap a couple of entries for garbage collection. Applied, thanks. -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Mon, Jul 09, 2018 at 05:43:22PM +0200, Pablo Neira Ayuso wrote: > On Mon, Jun 18, 2018 at 01:20:09AM -0700, Yi-Hung Wei wrote: > > From: Florian Westphal <fw@strlen.de> > > > > We use an extra function with early exit for garbage collection. > > It is not necessary to traverse the full list for every node since > > it is enough to zap a couple of entries for garbage collection. > > Applied, thanks. Sorry, I looked at the wrong series. Ignore this. Thanks. -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c index d8383609fe28..ed87ad40541b 100644 --- a/net/netfilter/nf_conncount.c +++ b/net/netfilter/nf_conncount.c @@ -147,6 +147,43 @@ unsigned int nf_conncount_lookup(struct net *net, struct hlist_head *head, } EXPORT_SYMBOL_GPL(nf_conncount_lookup); +static void nf_conncount_gc_list(struct net *net, + struct nf_conncount_rb *rbconn) +{ + const struct nf_conntrack_tuple_hash *found; + struct nf_conncount_tuple *conn; + struct hlist_node *n; + struct nf_conn *found_ct; + unsigned int collected = 0; + + hlist_for_each_entry_safe(conn, n, &rbconn->hhead, node) { + found = nf_conntrack_find_get(net, &conn->zone, &conn->tuple); + if (found == NULL) { + hlist_del(&conn->node); + kmem_cache_free(conncount_conn_cachep, conn); + collected++; + continue; + } + + found_ct = nf_ct_tuplehash_to_ctrack(found); + if (already_closed(found_ct)) { + /* + * we do not care about connections which are + * closed already -> ditch it + */ + nf_ct_put(found_ct); + hlist_del(&conn->node); + kmem_cache_free(conncount_conn_cachep, conn); + collected++; + continue; + } + + nf_ct_put(found_ct); + if (collected > CONNCOUNT_GC_MAX_NODES) + return; + } +} + static void tree_nodes_free(struct rb_root *root, struct nf_conncount_rb *gc_nodes[], unsigned int gc_count) @@ -209,8 +246,7 @@ count_tree(struct net *net, struct rb_root *root, if (no_gc || gc_count >= ARRAY_SIZE(gc_nodes)) continue; - /* only used for GC on hhead, retval and 'addit' ignored */ - nf_conncount_lookup(net, &rbconn->hhead, tuple, zone, &addit); + nf_conncount_gc_list(net, rbconn); if (hlist_empty(&rbconn->hhead)) gc_nodes[gc_count++] = rbconn; }