]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
drop netfilter-ipset-fix-performance-regression-in-swap-o.patch for now
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 5 Feb 2024 20:09:54 +0000 (20:09 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 5 Feb 2024 20:09:54 +0000 (20:09 +0000)
will come back later, it's broken

queue-6.6/netfilter-ipset-fix-performance-regression-in-swap-o.patch [deleted file]
queue-6.6/series
queue-6.7/netfilter-ipset-fix-performance-regression-in-swap-o.patch [deleted file]
queue-6.7/series

diff --git a/queue-6.6/netfilter-ipset-fix-performance-regression-in-swap-o.patch b/queue-6.6/netfilter-ipset-fix-performance-regression-in-swap-o.patch
deleted file mode 100644 (file)
index de91ddf..0000000
+++ /dev/null
@@ -1,301 +0,0 @@
-From a2337a34cfe7956a7342b96d41ccd74210fa8830 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 29 Jan 2024 10:57:01 +0100
-Subject: netfilter: ipset: fix performance regression in swap operation
-
-From: Jozsef Kadlecsik <kadlec@netfilter.org>
-
-[ Upstream commit 97f7cf1cd80eeed3b7c808b7c12463295c751001 ]
-
-The patch "netfilter: ipset: fix race condition between swap/destroy
-and kernel side add/del/test", commit 28628fa9 fixes a race condition.
-But the synchronize_rcu() added to the swap function unnecessarily slows
-it down: it can safely be moved to destroy and use call_rcu() instead.
-
-Eric Dumazet pointed out that simply calling the destroy functions as
-rcu callback does not work: sets with timeout use garbage collectors
-which need cancelling at destroy which can wait. Therefore the destroy
-functions are split into two: cancelling garbage collectors safely at
-executing the command received by netlink and moving the remaining
-part only into the rcu callback.
-
-Link: https://lore.kernel.org/lkml/C0829B10-EAA6-4809-874E-E1E9C05A8D84@automattic.com/
-Fixes: 28628fa952fe ("netfilter: ipset: fix race condition between swap/destroy and kernel side add/del/test")
-Reported-by: Ale Crismani <ale.crismani@automattic.com>
-Reported-by: David Wang <00107082@163.com>
-Tested-by: David Wang <00107082@163.com>
-Signed-off-by: Jozsef Kadlecsik <kadlec@netfilter.org>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/linux/netfilter/ipset/ip_set.h  |  4 +++
- net/netfilter/ipset/ip_set_bitmap_gen.h | 14 ++++++++--
- net/netfilter/ipset/ip_set_core.c       | 37 +++++++++++++++++++------
- net/netfilter/ipset/ip_set_hash_gen.h   | 15 ++++++++--
- net/netfilter/ipset/ip_set_list_set.c   | 13 +++++++--
- 5 files changed, 65 insertions(+), 18 deletions(-)
-
-diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h
-index e8c350a3ade1..e9f4f845d760 100644
---- a/include/linux/netfilter/ipset/ip_set.h
-+++ b/include/linux/netfilter/ipset/ip_set.h
-@@ -186,6 +186,8 @@ struct ip_set_type_variant {
-       /* Return true if "b" set is the same as "a"
-        * according to the create set parameters */
-       bool (*same_set)(const struct ip_set *a, const struct ip_set *b);
-+      /* Cancel ongoing garbage collectors before destroying the set*/
-+      void (*cancel_gc)(struct ip_set *set);
-       /* Region-locking is used */
-       bool region_lock;
- };
-@@ -242,6 +244,8 @@ extern void ip_set_type_unregister(struct ip_set_type *set_type);
- /* A generic IP set */
- struct ip_set {
-+      /* For call_cru in destroy */
-+      struct rcu_head rcu;
-       /* The name of the set */
-       char name[IPSET_MAXNAMELEN];
-       /* Lock protecting the set data */
-diff --git a/net/netfilter/ipset/ip_set_bitmap_gen.h b/net/netfilter/ipset/ip_set_bitmap_gen.h
-index 26ab0e9612d8..9523104a90da 100644
---- a/net/netfilter/ipset/ip_set_bitmap_gen.h
-+++ b/net/netfilter/ipset/ip_set_bitmap_gen.h
-@@ -28,6 +28,7 @@
- #define mtype_del             IPSET_TOKEN(MTYPE, _del)
- #define mtype_list            IPSET_TOKEN(MTYPE, _list)
- #define mtype_gc              IPSET_TOKEN(MTYPE, _gc)
-+#define mtype_cancel_gc               IPSET_TOKEN(MTYPE, _cancel_gc)
- #define mtype                 MTYPE
- #define get_ext(set, map, id) ((map)->extensions + ((set)->dsize * (id)))
-@@ -57,9 +58,6 @@ mtype_destroy(struct ip_set *set)
- {
-       struct mtype *map = set->data;
--      if (SET_WITH_TIMEOUT(set))
--              del_timer_sync(&map->gc);
--
-       if (set->dsize && set->extensions & IPSET_EXT_DESTROY)
-               mtype_ext_cleanup(set);
-       ip_set_free(map->members);
-@@ -288,6 +286,15 @@ mtype_gc(struct timer_list *t)
-       add_timer(&map->gc);
- }
-+static void
-+mtype_cancel_gc(struct ip_set *set)
-+{
-+      struct mtype *map = set->data;
-+
-+      if (SET_WITH_TIMEOUT(set))
-+              del_timer_sync(&map->gc);
-+}
-+
- static const struct ip_set_type_variant mtype = {
-       .kadt   = mtype_kadt,
-       .uadt   = mtype_uadt,
-@@ -301,6 +308,7 @@ static const struct ip_set_type_variant mtype = {
-       .head   = mtype_head,
-       .list   = mtype_list,
-       .same_set = mtype_same_set,
-+      .cancel_gc = mtype_cancel_gc,
- };
- #endif /* __IP_SET_BITMAP_IP_GEN_H */
-diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
-index 4c133e06be1d..bcaad9c009fe 100644
---- a/net/netfilter/ipset/ip_set_core.c
-+++ b/net/netfilter/ipset/ip_set_core.c
-@@ -1182,6 +1182,14 @@ ip_set_destroy_set(struct ip_set *set)
-       kfree(set);
- }
-+static void
-+ip_set_destroy_set_rcu(struct rcu_head *head)
-+{
-+      struct ip_set *set = container_of(head, struct ip_set, rcu);
-+
-+      ip_set_destroy_set(set);
-+}
-+
- static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info,
-                         const struct nlattr * const attr[])
- {
-@@ -1193,8 +1201,6 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info,
-       if (unlikely(protocol_min_failed(attr)))
-               return -IPSET_ERR_PROTOCOL;
--      /* Must wait for flush to be really finished in list:set */
--      rcu_barrier();
-       /* Commands are serialized and references are
-        * protected by the ip_set_ref_lock.
-@@ -1206,8 +1212,10 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info,
-        * counter, so if it's already zero, we can proceed
-        * without holding the lock.
-        */
--      read_lock_bh(&ip_set_ref_lock);
-       if (!attr[IPSET_ATTR_SETNAME]) {
-+              /* Must wait for flush to be really finished in list:set */
-+              rcu_barrier();
-+              read_lock_bh(&ip_set_ref_lock);
-               for (i = 0; i < inst->ip_set_max; i++) {
-                       s = ip_set(inst, i);
-                       if (s && (s->ref || s->ref_netlink)) {
-@@ -1221,6 +1229,8 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info,
-                       s = ip_set(inst, i);
-                       if (s) {
-                               ip_set(inst, i) = NULL;
-+                              /* Must cancel garbage collectors */
-+                              s->variant->cancel_gc(s);
-                               ip_set_destroy_set(s);
-                       }
-               }
-@@ -1228,6 +1238,9 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info,
-               inst->is_destroyed = false;
-       } else {
-               u32 flags = flag_exist(info->nlh);
-+              u16 features = 0;
-+
-+              read_lock_bh(&ip_set_ref_lock);
-               s = find_set_and_id(inst, nla_data(attr[IPSET_ATTR_SETNAME]),
-                                   &i);
-               if (!s) {
-@@ -1238,10 +1251,16 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info,
-                       ret = -IPSET_ERR_BUSY;
-                       goto out;
-               }
-+              features = s->type->features;
-               ip_set(inst, i) = NULL;
-               read_unlock_bh(&ip_set_ref_lock);
--
--              ip_set_destroy_set(s);
-+              if (features & IPSET_TYPE_NAME) {
-+                      /* Must wait for flush to be really finished  */
-+                      rcu_barrier();
-+              }
-+              /* Must cancel garbage collectors */
-+              s->variant->cancel_gc(s);
-+              call_rcu(&s->rcu, ip_set_destroy_set_rcu);
-       }
-       return 0;
- out:
-@@ -1394,9 +1413,6 @@ static int ip_set_swap(struct sk_buff *skb, const struct nfnl_info *info,
-       ip_set(inst, to_id) = from;
-       write_unlock_bh(&ip_set_ref_lock);
--      /* Make sure all readers of the old set pointers are completed. */
--      synchronize_rcu();
--
-       return 0;
- }
-@@ -2409,8 +2425,11 @@ ip_set_fini(void)
- {
-       nf_unregister_sockopt(&so_set);
-       nfnetlink_subsys_unregister(&ip_set_netlink_subsys);
--
-       unregister_pernet_subsys(&ip_set_net_ops);
-+
-+      /* Wait for call_rcu() in destroy */
-+      rcu_barrier();
-+
-       pr_debug("these are the famous last words\n");
- }
-diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h
-index 7c2399541771..c62998b46f00 100644
---- a/net/netfilter/ipset/ip_set_hash_gen.h
-+++ b/net/netfilter/ipset/ip_set_hash_gen.h
-@@ -221,6 +221,7 @@ static const union nf_inet_addr zeromask = {};
- #undef mtype_gc_do
- #undef mtype_gc
- #undef mtype_gc_init
-+#undef mtype_cancel_gc
- #undef mtype_variant
- #undef mtype_data_match
-@@ -265,6 +266,7 @@ static const union nf_inet_addr zeromask = {};
- #define mtype_gc_do           IPSET_TOKEN(MTYPE, _gc_do)
- #define mtype_gc              IPSET_TOKEN(MTYPE, _gc)
- #define mtype_gc_init         IPSET_TOKEN(MTYPE, _gc_init)
-+#define mtype_cancel_gc               IPSET_TOKEN(MTYPE, _cancel_gc)
- #define mtype_variant         IPSET_TOKEN(MTYPE, _variant)
- #define mtype_data_match      IPSET_TOKEN(MTYPE, _data_match)
-@@ -449,9 +451,6 @@ mtype_destroy(struct ip_set *set)
-       struct htype *h = set->data;
-       struct list_head *l, *lt;
--      if (SET_WITH_TIMEOUT(set))
--              cancel_delayed_work_sync(&h->gc.dwork);
--
-       mtype_ahash_destroy(set, ipset_dereference_nfnl(h->table), true);
-       list_for_each_safe(l, lt, &h->ad) {
-               list_del(l);
-@@ -598,6 +597,15 @@ mtype_gc_init(struct htable_gc *gc)
-       queue_delayed_work(system_power_efficient_wq, &gc->dwork, HZ);
- }
-+static void
-+mtype_cancel_gc(struct ip_set *set)
-+{
-+      struct htype *h = set->data;
-+
-+      if (SET_WITH_TIMEOUT(set))
-+              cancel_delayed_work_sync(&h->gc.dwork);
-+}
-+
- static int
- mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
-         struct ip_set_ext *mext, u32 flags);
-@@ -1440,6 +1448,7 @@ static const struct ip_set_type_variant mtype_variant = {
-       .uref   = mtype_uref,
-       .resize = mtype_resize,
-       .same_set = mtype_same_set,
-+      .cancel_gc = mtype_cancel_gc,
-       .region_lock = true,
- };
-diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c
-index e162636525cf..6c3f28bc59b3 100644
---- a/net/netfilter/ipset/ip_set_list_set.c
-+++ b/net/netfilter/ipset/ip_set_list_set.c
-@@ -426,9 +426,6 @@ list_set_destroy(struct ip_set *set)
-       struct list_set *map = set->data;
-       struct set_elem *e, *n;
--      if (SET_WITH_TIMEOUT(set))
--              timer_shutdown_sync(&map->gc);
--
-       list_for_each_entry_safe(e, n, &map->members, list) {
-               list_del(&e->list);
-               ip_set_put_byindex(map->net, e->id);
-@@ -545,6 +542,15 @@ list_set_same_set(const struct ip_set *a, const struct ip_set *b)
-              a->extensions == b->extensions;
- }
-+static void
-+list_set_cancel_gc(struct ip_set *set)
-+{
-+      struct list_set *map = set->data;
-+
-+      if (SET_WITH_TIMEOUT(set))
-+              timer_shutdown_sync(&map->gc);
-+}
-+
- static const struct ip_set_type_variant set_variant = {
-       .kadt   = list_set_kadt,
-       .uadt   = list_set_uadt,
-@@ -558,6 +564,7 @@ static const struct ip_set_type_variant set_variant = {
-       .head   = list_set_head,
-       .list   = list_set_list,
-       .same_set = list_set_same_set,
-+      .cancel_gc = list_set_cancel_gc,
- };
- static void
--- 
-2.43.0
-
index 767fac348108640f29a347af88c14f5000ee5eb4..5c67f5fa811356cf2115c7a318dffbfb5596aa0e 100644 (file)
@@ -290,7 +290,6 @@ devlink-fix-referring-to-hw_addr-attribute-during-st.patch
 selftests-net-add-missing-config-for-geneve.patch
 netfilter-conntrack-correct-window-scaling-with-retr.patch
 netfilter-nf_tables-restrict-tunnel-object-to-nfprot.patch
-netfilter-ipset-fix-performance-regression-in-swap-o.patch
 netfilter-nf_log-replace-bug_on-by-warn_on_once-when.patch
 netfilter-nft_ct-sanitize-layer-3-and-4-protocol-num.patch
 net-ipv4-fix-a-memleak-in-ip_setup_cork.patch
diff --git a/queue-6.7/netfilter-ipset-fix-performance-regression-in-swap-o.patch b/queue-6.7/netfilter-ipset-fix-performance-regression-in-swap-o.patch
deleted file mode 100644 (file)
index 4fb27fc..0000000
+++ /dev/null
@@ -1,301 +0,0 @@
-From 6a8adccadfffd99869f8d4073b7d1a173906f8cb Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 29 Jan 2024 10:57:01 +0100
-Subject: netfilter: ipset: fix performance regression in swap operation
-
-From: Jozsef Kadlecsik <kadlec@netfilter.org>
-
-[ Upstream commit 97f7cf1cd80eeed3b7c808b7c12463295c751001 ]
-
-The patch "netfilter: ipset: fix race condition between swap/destroy
-and kernel side add/del/test", commit 28628fa9 fixes a race condition.
-But the synchronize_rcu() added to the swap function unnecessarily slows
-it down: it can safely be moved to destroy and use call_rcu() instead.
-
-Eric Dumazet pointed out that simply calling the destroy functions as
-rcu callback does not work: sets with timeout use garbage collectors
-which need cancelling at destroy which can wait. Therefore the destroy
-functions are split into two: cancelling garbage collectors safely at
-executing the command received by netlink and moving the remaining
-part only into the rcu callback.
-
-Link: https://lore.kernel.org/lkml/C0829B10-EAA6-4809-874E-E1E9C05A8D84@automattic.com/
-Fixes: 28628fa952fe ("netfilter: ipset: fix race condition between swap/destroy and kernel side add/del/test")
-Reported-by: Ale Crismani <ale.crismani@automattic.com>
-Reported-by: David Wang <00107082@163.com>
-Tested-by: David Wang <00107082@163.com>
-Signed-off-by: Jozsef Kadlecsik <kadlec@netfilter.org>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/linux/netfilter/ipset/ip_set.h  |  4 +++
- net/netfilter/ipset/ip_set_bitmap_gen.h | 14 ++++++++--
- net/netfilter/ipset/ip_set_core.c       | 37 +++++++++++++++++++------
- net/netfilter/ipset/ip_set_hash_gen.h   | 15 ++++++++--
- net/netfilter/ipset/ip_set_list_set.c   | 13 +++++++--
- 5 files changed, 65 insertions(+), 18 deletions(-)
-
-diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h
-index e8c350a3ade1..e9f4f845d760 100644
---- a/include/linux/netfilter/ipset/ip_set.h
-+++ b/include/linux/netfilter/ipset/ip_set.h
-@@ -186,6 +186,8 @@ struct ip_set_type_variant {
-       /* Return true if "b" set is the same as "a"
-        * according to the create set parameters */
-       bool (*same_set)(const struct ip_set *a, const struct ip_set *b);
-+      /* Cancel ongoing garbage collectors before destroying the set*/
-+      void (*cancel_gc)(struct ip_set *set);
-       /* Region-locking is used */
-       bool region_lock;
- };
-@@ -242,6 +244,8 @@ extern void ip_set_type_unregister(struct ip_set_type *set_type);
- /* A generic IP set */
- struct ip_set {
-+      /* For call_cru in destroy */
-+      struct rcu_head rcu;
-       /* The name of the set */
-       char name[IPSET_MAXNAMELEN];
-       /* Lock protecting the set data */
-diff --git a/net/netfilter/ipset/ip_set_bitmap_gen.h b/net/netfilter/ipset/ip_set_bitmap_gen.h
-index 26ab0e9612d8..9523104a90da 100644
---- a/net/netfilter/ipset/ip_set_bitmap_gen.h
-+++ b/net/netfilter/ipset/ip_set_bitmap_gen.h
-@@ -28,6 +28,7 @@
- #define mtype_del             IPSET_TOKEN(MTYPE, _del)
- #define mtype_list            IPSET_TOKEN(MTYPE, _list)
- #define mtype_gc              IPSET_TOKEN(MTYPE, _gc)
-+#define mtype_cancel_gc               IPSET_TOKEN(MTYPE, _cancel_gc)
- #define mtype                 MTYPE
- #define get_ext(set, map, id) ((map)->extensions + ((set)->dsize * (id)))
-@@ -57,9 +58,6 @@ mtype_destroy(struct ip_set *set)
- {
-       struct mtype *map = set->data;
--      if (SET_WITH_TIMEOUT(set))
--              del_timer_sync(&map->gc);
--
-       if (set->dsize && set->extensions & IPSET_EXT_DESTROY)
-               mtype_ext_cleanup(set);
-       ip_set_free(map->members);
-@@ -288,6 +286,15 @@ mtype_gc(struct timer_list *t)
-       add_timer(&map->gc);
- }
-+static void
-+mtype_cancel_gc(struct ip_set *set)
-+{
-+      struct mtype *map = set->data;
-+
-+      if (SET_WITH_TIMEOUT(set))
-+              del_timer_sync(&map->gc);
-+}
-+
- static const struct ip_set_type_variant mtype = {
-       .kadt   = mtype_kadt,
-       .uadt   = mtype_uadt,
-@@ -301,6 +308,7 @@ static const struct ip_set_type_variant mtype = {
-       .head   = mtype_head,
-       .list   = mtype_list,
-       .same_set = mtype_same_set,
-+      .cancel_gc = mtype_cancel_gc,
- };
- #endif /* __IP_SET_BITMAP_IP_GEN_H */
-diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
-index 4c133e06be1d..bcaad9c009fe 100644
---- a/net/netfilter/ipset/ip_set_core.c
-+++ b/net/netfilter/ipset/ip_set_core.c
-@@ -1182,6 +1182,14 @@ ip_set_destroy_set(struct ip_set *set)
-       kfree(set);
- }
-+static void
-+ip_set_destroy_set_rcu(struct rcu_head *head)
-+{
-+      struct ip_set *set = container_of(head, struct ip_set, rcu);
-+
-+      ip_set_destroy_set(set);
-+}
-+
- static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info,
-                         const struct nlattr * const attr[])
- {
-@@ -1193,8 +1201,6 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info,
-       if (unlikely(protocol_min_failed(attr)))
-               return -IPSET_ERR_PROTOCOL;
--      /* Must wait for flush to be really finished in list:set */
--      rcu_barrier();
-       /* Commands are serialized and references are
-        * protected by the ip_set_ref_lock.
-@@ -1206,8 +1212,10 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info,
-        * counter, so if it's already zero, we can proceed
-        * without holding the lock.
-        */
--      read_lock_bh(&ip_set_ref_lock);
-       if (!attr[IPSET_ATTR_SETNAME]) {
-+              /* Must wait for flush to be really finished in list:set */
-+              rcu_barrier();
-+              read_lock_bh(&ip_set_ref_lock);
-               for (i = 0; i < inst->ip_set_max; i++) {
-                       s = ip_set(inst, i);
-                       if (s && (s->ref || s->ref_netlink)) {
-@@ -1221,6 +1229,8 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info,
-                       s = ip_set(inst, i);
-                       if (s) {
-                               ip_set(inst, i) = NULL;
-+                              /* Must cancel garbage collectors */
-+                              s->variant->cancel_gc(s);
-                               ip_set_destroy_set(s);
-                       }
-               }
-@@ -1228,6 +1238,9 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info,
-               inst->is_destroyed = false;
-       } else {
-               u32 flags = flag_exist(info->nlh);
-+              u16 features = 0;
-+
-+              read_lock_bh(&ip_set_ref_lock);
-               s = find_set_and_id(inst, nla_data(attr[IPSET_ATTR_SETNAME]),
-                                   &i);
-               if (!s) {
-@@ -1238,10 +1251,16 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info,
-                       ret = -IPSET_ERR_BUSY;
-                       goto out;
-               }
-+              features = s->type->features;
-               ip_set(inst, i) = NULL;
-               read_unlock_bh(&ip_set_ref_lock);
--
--              ip_set_destroy_set(s);
-+              if (features & IPSET_TYPE_NAME) {
-+                      /* Must wait for flush to be really finished  */
-+                      rcu_barrier();
-+              }
-+              /* Must cancel garbage collectors */
-+              s->variant->cancel_gc(s);
-+              call_rcu(&s->rcu, ip_set_destroy_set_rcu);
-       }
-       return 0;
- out:
-@@ -1394,9 +1413,6 @@ static int ip_set_swap(struct sk_buff *skb, const struct nfnl_info *info,
-       ip_set(inst, to_id) = from;
-       write_unlock_bh(&ip_set_ref_lock);
--      /* Make sure all readers of the old set pointers are completed. */
--      synchronize_rcu();
--
-       return 0;
- }
-@@ -2409,8 +2425,11 @@ ip_set_fini(void)
- {
-       nf_unregister_sockopt(&so_set);
-       nfnetlink_subsys_unregister(&ip_set_netlink_subsys);
--
-       unregister_pernet_subsys(&ip_set_net_ops);
-+
-+      /* Wait for call_rcu() in destroy */
-+      rcu_barrier();
-+
-       pr_debug("these are the famous last words\n");
- }
-diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h
-index 7c2399541771..c62998b46f00 100644
---- a/net/netfilter/ipset/ip_set_hash_gen.h
-+++ b/net/netfilter/ipset/ip_set_hash_gen.h
-@@ -221,6 +221,7 @@ static const union nf_inet_addr zeromask = {};
- #undef mtype_gc_do
- #undef mtype_gc
- #undef mtype_gc_init
-+#undef mtype_cancel_gc
- #undef mtype_variant
- #undef mtype_data_match
-@@ -265,6 +266,7 @@ static const union nf_inet_addr zeromask = {};
- #define mtype_gc_do           IPSET_TOKEN(MTYPE, _gc_do)
- #define mtype_gc              IPSET_TOKEN(MTYPE, _gc)
- #define mtype_gc_init         IPSET_TOKEN(MTYPE, _gc_init)
-+#define mtype_cancel_gc               IPSET_TOKEN(MTYPE, _cancel_gc)
- #define mtype_variant         IPSET_TOKEN(MTYPE, _variant)
- #define mtype_data_match      IPSET_TOKEN(MTYPE, _data_match)
-@@ -449,9 +451,6 @@ mtype_destroy(struct ip_set *set)
-       struct htype *h = set->data;
-       struct list_head *l, *lt;
--      if (SET_WITH_TIMEOUT(set))
--              cancel_delayed_work_sync(&h->gc.dwork);
--
-       mtype_ahash_destroy(set, ipset_dereference_nfnl(h->table), true);
-       list_for_each_safe(l, lt, &h->ad) {
-               list_del(l);
-@@ -598,6 +597,15 @@ mtype_gc_init(struct htable_gc *gc)
-       queue_delayed_work(system_power_efficient_wq, &gc->dwork, HZ);
- }
-+static void
-+mtype_cancel_gc(struct ip_set *set)
-+{
-+      struct htype *h = set->data;
-+
-+      if (SET_WITH_TIMEOUT(set))
-+              cancel_delayed_work_sync(&h->gc.dwork);
-+}
-+
- static int
- mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
-         struct ip_set_ext *mext, u32 flags);
-@@ -1440,6 +1448,7 @@ static const struct ip_set_type_variant mtype_variant = {
-       .uref   = mtype_uref,
-       .resize = mtype_resize,
-       .same_set = mtype_same_set,
-+      .cancel_gc = mtype_cancel_gc,
-       .region_lock = true,
- };
-diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c
-index e162636525cf..6c3f28bc59b3 100644
---- a/net/netfilter/ipset/ip_set_list_set.c
-+++ b/net/netfilter/ipset/ip_set_list_set.c
-@@ -426,9 +426,6 @@ list_set_destroy(struct ip_set *set)
-       struct list_set *map = set->data;
-       struct set_elem *e, *n;
--      if (SET_WITH_TIMEOUT(set))
--              timer_shutdown_sync(&map->gc);
--
-       list_for_each_entry_safe(e, n, &map->members, list) {
-               list_del(&e->list);
-               ip_set_put_byindex(map->net, e->id);
-@@ -545,6 +542,15 @@ list_set_same_set(const struct ip_set *a, const struct ip_set *b)
-              a->extensions == b->extensions;
- }
-+static void
-+list_set_cancel_gc(struct ip_set *set)
-+{
-+      struct list_set *map = set->data;
-+
-+      if (SET_WITH_TIMEOUT(set))
-+              timer_shutdown_sync(&map->gc);
-+}
-+
- static const struct ip_set_type_variant set_variant = {
-       .kadt   = list_set_kadt,
-       .uadt   = list_set_uadt,
-@@ -558,6 +564,7 @@ static const struct ip_set_type_variant set_variant = {
-       .head   = list_set_head,
-       .list   = list_set_list,
-       .same_set = list_set_same_set,
-+      .cancel_gc = list_set_cancel_gc,
- };
- static void
--- 
-2.43.0
-
index bfc242b7e554daa0a8a8593d58c0eb2575b7809e..0afabec0e83fed47172873a7f148f352ace347fb 100644 (file)
@@ -320,7 +320,6 @@ devlink-fix-referring-to-hw_addr-attribute-during-st.patch
 selftests-net-add-missing-config-for-geneve.patch
 netfilter-conntrack-correct-window-scaling-with-retr.patch
 netfilter-nf_tables-restrict-tunnel-object-to-nfprot.patch
-netfilter-ipset-fix-performance-regression-in-swap-o.patch
 netfilter-nf_log-replace-bug_on-by-warn_on_once-when.patch
 netfilter-nft_ct-sanitize-layer-3-and-4-protocol-num.patch
 net-ipv4-fix-a-memleak-in-ip_setup_cork.patch