Merge tag 'vfio-v5.11-rc1' of git://github.com/awilliam/linux-vfio
[linux-2.6-microblaze.git] / net / netfilter / nft_set_hash.c
index 4d3f147..bf618b7 100644 (file)
@@ -293,6 +293,22 @@ cont:
        rhashtable_walk_exit(&hti);
 }
 
+static bool nft_rhash_expr_needs_gc_run(const struct nft_set *set,
+                                       struct nft_set_ext *ext)
+{
+       struct nft_set_elem_expr *elem_expr = nft_set_ext_expr(ext);
+       struct nft_expr *expr;
+       u32 size;
+
+       nft_setelem_expr_foreach(expr, elem_expr, size) {
+               if (expr->ops->gc &&
+                   expr->ops->gc(read_pnet(&set->net), expr))
+                       return true;
+       }
+
+       return false;
+}
+
 static void nft_rhash_gc(struct work_struct *work)
 {
        struct nft_set *set;
@@ -314,16 +330,13 @@ static void nft_rhash_gc(struct work_struct *work)
                        continue;
                }
 
-               if (nft_set_ext_exists(&he->ext, NFT_SET_EXT_EXPR)) {
-                       struct nft_expr *expr = nft_set_ext_expr(&he->ext);
+               if (nft_set_ext_exists(&he->ext, NFT_SET_EXT_EXPRESSIONS) &&
+                   nft_rhash_expr_needs_gc_run(set, &he->ext))
+                       goto needs_gc_run;
 
-                       if (expr->ops->gc &&
-                           expr->ops->gc(read_pnet(&set->net), expr))
-                               goto gc;
-               }
                if (!nft_set_elem_expired(&he->ext))
                        continue;
-gc:
+needs_gc_run:
                if (nft_set_elem_mark_busy(&he->ext))
                        continue;