diff options
-rw-r--r-- | drivers/net/team/team_mode_loadbalance.c | 6 | ||||
-rw-r--r-- | net/core/filter.c | 11 |
2 files changed, 13 insertions, 4 deletions
diff --git a/drivers/net/team/team_mode_loadbalance.c b/drivers/net/team/team_mode_loadbalance.c index a58dfebb5512..7106f3456439 100644 --- a/drivers/net/team/team_mode_loadbalance.c +++ b/drivers/net/team/team_mode_loadbalance.c | |||
@@ -293,11 +293,15 @@ static int lb_bpf_func_set(struct team *team, struct team_gsetter_ctx *ctx) | |||
293 | __fprog_destroy(lb_priv->ex->orig_fprog); | 293 | __fprog_destroy(lb_priv->ex->orig_fprog); |
294 | orig_fp = rcu_dereference_protected(lb_priv->fp, | 294 | orig_fp = rcu_dereference_protected(lb_priv->fp, |
295 | lockdep_is_held(&team->lock)); | 295 | lockdep_is_held(&team->lock)); |
296 | sk_unattached_filter_destroy(orig_fp); | ||
297 | } | 296 | } |
298 | 297 | ||
299 | rcu_assign_pointer(lb_priv->fp, fp); | 298 | rcu_assign_pointer(lb_priv->fp, fp); |
300 | lb_priv->ex->orig_fprog = fprog; | 299 | lb_priv->ex->orig_fprog = fprog; |
300 | |||
301 | if (orig_fp) { | ||
302 | synchronize_rcu(); | ||
303 | sk_unattached_filter_destroy(orig_fp); | ||
304 | } | ||
301 | return 0; | 305 | return 0; |
302 | } | 306 | } |
303 | 307 | ||
diff --git a/net/core/filter.c b/net/core/filter.c index f3b2d5e9fe5f..42c1944b0c63 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -841,6 +841,12 @@ static void sk_release_orig_filter(struct sk_filter *fp) | |||
841 | } | 841 | } |
842 | } | 842 | } |
843 | 843 | ||
844 | static void __sk_filter_release(struct sk_filter *fp) | ||
845 | { | ||
846 | sk_release_orig_filter(fp); | ||
847 | sk_filter_free(fp); | ||
848 | } | ||
849 | |||
844 | /** | 850 | /** |
845 | * sk_filter_release_rcu - Release a socket filter by rcu_head | 851 | * sk_filter_release_rcu - Release a socket filter by rcu_head |
846 | * @rcu: rcu_head that contains the sk_filter to free | 852 | * @rcu: rcu_head that contains the sk_filter to free |
@@ -849,8 +855,7 @@ static void sk_filter_release_rcu(struct rcu_head *rcu) | |||
849 | { | 855 | { |
850 | struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu); | 856 | struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu); |
851 | 857 | ||
852 | sk_release_orig_filter(fp); | 858 | __sk_filter_release(fp); |
853 | sk_filter_free(fp); | ||
854 | } | 859 | } |
855 | 860 | ||
856 | /** | 861 | /** |
@@ -1050,7 +1055,7 @@ EXPORT_SYMBOL_GPL(sk_unattached_filter_create); | |||
1050 | 1055 | ||
1051 | void sk_unattached_filter_destroy(struct sk_filter *fp) | 1056 | void sk_unattached_filter_destroy(struct sk_filter *fp) |
1052 | { | 1057 | { |
1053 | sk_filter_release(fp); | 1058 | __sk_filter_release(fp); |
1054 | } | 1059 | } |
1055 | EXPORT_SYMBOL_GPL(sk_unattached_filter_destroy); | 1060 | EXPORT_SYMBOL_GPL(sk_unattached_filter_destroy); |
1056 | 1061 | ||