}
 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 = find_or_evict(net, conn);
+               if (IS_ERR(found)) {
+                       if (PTR_ERR(found) == -ENOENT)
+                               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)
                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;
        }