call_rcu(&trans->rcu, nft_trans_gc_trans_free);
 }
 
-static struct nft_trans_gc *nft_trans_gc_catchall(struct nft_trans_gc *gc,
-                                                 unsigned int gc_seq,
-                                                 bool sync)
+struct nft_trans_gc *nft_trans_gc_catchall_async(struct nft_trans_gc *gc,
+                                                unsigned int gc_seq)
 {
-       struct nft_set_elem_catchall *catchall, *next;
+       struct nft_set_elem_catchall *catchall;
        const struct nft_set *set = gc->set;
-       struct nft_elem_priv *elem_priv;
        struct nft_set_ext *ext;
 
-       list_for_each_entry_safe(catchall, next, &set->catchall_list, list) {
+       list_for_each_entry_rcu(catchall, &set->catchall_list, list) {
                ext = nft_set_elem_ext(set, catchall->elem);
 
                if (!nft_set_elem_expired(ext))
 
                nft_set_elem_dead(ext);
 dead_elem:
-               if (sync)
-                       gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC);
-               else
-                       gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC);
-
+               gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC);
                if (!gc)
                        return NULL;
 
-               elem_priv = catchall->elem;
-               if (sync) {
-                       nft_setelem_data_deactivate(gc->net, gc->set, elem_priv);
-                       nft_setelem_catchall_destroy(catchall);
-               }
-
-               nft_trans_gc_elem_add(gc, elem_priv);
+               nft_trans_gc_elem_add(gc, catchall->elem);
        }
 
        return gc;
 }
 
-struct nft_trans_gc *nft_trans_gc_catchall_async(struct nft_trans_gc *gc,
-                                                unsigned int gc_seq)
-{
-       return nft_trans_gc_catchall(gc, gc_seq, false);
-}
-
 struct nft_trans_gc *nft_trans_gc_catchall_sync(struct nft_trans_gc *gc)
 {
-       return nft_trans_gc_catchall(gc, 0, true);
+       struct nft_set_elem_catchall *catchall, *next;
+       const struct nft_set *set = gc->set;
+       struct nft_elem_priv *elem_priv;
+       struct nft_set_ext *ext;
+
+       WARN_ON_ONCE(!lockdep_commit_lock_is_held(gc->net));
+
+       list_for_each_entry_safe(catchall, next, &set->catchall_list, list) {
+               ext = nft_set_elem_ext(set, catchall->elem);
+
+               if (!nft_set_elem_expired(ext))
+                       continue;
+
+               gc = nft_trans_gc_queue_sync(gc, GFP_KERNEL);
+               if (!gc)
+                       return NULL;
+
+               elem_priv = catchall->elem;
+               nft_setelem_data_deactivate(gc->net, gc->set, elem_priv);
+               nft_setelem_catchall_destroy(catchall);
+               nft_trans_gc_elem_add(gc, elem_priv);
+       }
+
+       return gc;
 }
 
 static void nf_tables_module_autoload_cleanup(struct net *net)