aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/team
diff options
context:
space:
mode:
authorPablo Neira <pablo@netfilter.org>2014-07-29 11:36:28 -0400
committerDavid S. Miller <davem@davemloft.net>2014-07-30 22:56:27 -0400
commit34c5bd66e5ed2268bcb917b4cbdd6317023eada4 (patch)
tree67735bf1114eaf2708176c912d3af00a1d7ebe1e /drivers/net/team
parente10038a8ec06ac819b7552bb67aaa6d2d6f850c1 (diff)
net: filter: don't release unattached filter through call_rcu()
sk_unattached_filter_destroy() does not always need to release the filter object via rcu. Since this filter is never attached to the socket, the caller should be responsible for releasing the filter in a safe way, which may not necessarily imply rcu. This is a short summary of clients of this function: 1) xt_bpf.c and cls_bpf.c use the bpf matchers from rules, these rules are removed from the packet path before the filter is released. Thus, the framework makes sure the filter is safely removed. 2) In the ppp driver, the ppp_lock ensures serialization between the xmit and filter attachment/detachment path. This doesn't use rcu so deferred release via rcu makes no sense. 3) In the isdn/ppp driver, it is called from isdn_ppp_release() the isdn_ppp_ioctl(). This driver uses mutex and spinlocks, no rcu. Thus, deferred rcu makes no sense to me either, the deferred releases may be just masking the effects of wrong locking strategy, which should be fixed in the driver itself. 4) In the team driver, this is the only place where the rcu synchronization with unattached filter is used. Therefore, this patch introduces synchronize_rcu() which is called from the genetlink path to make sure the filter doesn't go away while packets are still walking over it. I think we can revisit this once struct bpf_prog (that only wraps specific bpf code bits) is in place, then add some specific struct rcu_head in the scope of the team driver if Jiri thinks this is needed. Deferred rcu release for unattached filters was originally introduced in 302d663 ("filter: Allow to create sk-unattached filters"). Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/team')
-rw-r--r--drivers/net/team/team_mode_loadbalance.c6
1 files changed, 5 insertions, 1 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