xfrm: remove flow cache
After rcu conversions performance degradation in forward tests isn't that noticeable anymore. See next patch for some numbers. A followup patcg could then also remove genid from the policies as we do not cache bundles anymore. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
bd45c539bf
commit
09c7570480
@@ -175,8 +175,6 @@ static int xfrm_dev_down(struct net_device *dev)
|
||||
if (dev->features & NETIF_F_HW_ESP)
|
||||
xfrm_dev_state_flush(dev_net(dev), dev, true);
|
||||
|
||||
xfrm_garbage_collect(dev_net(dev));
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
|
@@ -246,36 +246,6 @@ expired:
|
||||
xfrm_pol_put(xp);
|
||||
}
|
||||
|
||||
static struct flow_cache_object *xfrm_policy_flo_get(struct flow_cache_object *flo)
|
||||
{
|
||||
struct xfrm_policy *pol = container_of(flo, struct xfrm_policy, flo);
|
||||
|
||||
if (unlikely(pol->walk.dead))
|
||||
flo = NULL;
|
||||
else
|
||||
xfrm_pol_hold(pol);
|
||||
|
||||
return flo;
|
||||
}
|
||||
|
||||
static int xfrm_policy_flo_check(struct flow_cache_object *flo)
|
||||
{
|
||||
struct xfrm_policy *pol = container_of(flo, struct xfrm_policy, flo);
|
||||
|
||||
return !pol->walk.dead;
|
||||
}
|
||||
|
||||
static void xfrm_policy_flo_delete(struct flow_cache_object *flo)
|
||||
{
|
||||
xfrm_pol_put(container_of(flo, struct xfrm_policy, flo));
|
||||
}
|
||||
|
||||
static const struct flow_cache_ops xfrm_policy_fc_ops = {
|
||||
.get = xfrm_policy_flo_get,
|
||||
.check = xfrm_policy_flo_check,
|
||||
.delete = xfrm_policy_flo_delete,
|
||||
};
|
||||
|
||||
/* Allocate xfrm_policy. Not used here, it is supposed to be used by pfkeyv2
|
||||
* SPD calls.
|
||||
*/
|
||||
@@ -298,7 +268,6 @@ struct xfrm_policy *xfrm_policy_alloc(struct net *net, gfp_t gfp)
|
||||
(unsigned long)policy);
|
||||
setup_timer(&policy->polq.hold_timer, xfrm_policy_queue_process,
|
||||
(unsigned long)policy);
|
||||
policy->flo.ops = &xfrm_policy_fc_ops;
|
||||
}
|
||||
return policy;
|
||||
}
|
||||
@@ -798,7 +767,6 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
|
||||
else
|
||||
hlist_add_head(&policy->bydst, chain);
|
||||
__xfrm_policy_link(policy, dir);
|
||||
atomic_inc(&net->xfrm.flow_cache_genid);
|
||||
|
||||
/* After previous checking, family can either be AF_INET or AF_INET6 */
|
||||
if (policy->family == AF_INET)
|
||||
@@ -1490,58 +1458,6 @@ static int xfrm_get_tos(const struct flowi *fl, int family)
|
||||
return tos;
|
||||
}
|
||||
|
||||
static struct flow_cache_object *xfrm_bundle_flo_get(struct flow_cache_object *flo)
|
||||
{
|
||||
struct xfrm_dst *xdst = container_of(flo, struct xfrm_dst, flo);
|
||||
struct dst_entry *dst = &xdst->u.dst;
|
||||
|
||||
if (xdst->route == NULL) {
|
||||
/* Dummy bundle - if it has xfrms we were not
|
||||
* able to build bundle as template resolution failed.
|
||||
* It means we need to try again resolving. */
|
||||
if (xdst->num_xfrms > 0)
|
||||
return NULL;
|
||||
} else if (dst->flags & DST_XFRM_QUEUE) {
|
||||
return NULL;
|
||||
} else {
|
||||
/* Real bundle */
|
||||
if (stale_bundle(dst))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dst_hold(dst);
|
||||
return flo;
|
||||
}
|
||||
|
||||
static int xfrm_bundle_flo_check(struct flow_cache_object *flo)
|
||||
{
|
||||
struct xfrm_dst *xdst = container_of(flo, struct xfrm_dst, flo);
|
||||
struct dst_entry *dst = &xdst->u.dst;
|
||||
|
||||
if (!xdst->route)
|
||||
return 0;
|
||||
if (stale_bundle(dst))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void xfrm_bundle_flo_delete(struct flow_cache_object *flo)
|
||||
{
|
||||
struct xfrm_dst *xdst = container_of(flo, struct xfrm_dst, flo);
|
||||
struct dst_entry *dst = &xdst->u.dst;
|
||||
|
||||
/* Mark DST_OBSOLETE_DEAD to fail the next xfrm_dst_check() */
|
||||
dst->obsolete = DST_OBSOLETE_DEAD;
|
||||
dst_release_immediate(dst);
|
||||
}
|
||||
|
||||
static const struct flow_cache_ops xfrm_bundle_fc_ops = {
|
||||
.get = xfrm_bundle_flo_get,
|
||||
.check = xfrm_bundle_flo_check,
|
||||
.delete = xfrm_bundle_flo_delete,
|
||||
};
|
||||
|
||||
static inline struct xfrm_dst *xfrm_alloc_dst(struct net *net, int family)
|
||||
{
|
||||
const struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);
|
||||
@@ -1569,7 +1485,6 @@ static inline struct xfrm_dst *xfrm_alloc_dst(struct net *net, int family)
|
||||
struct dst_entry *dst = &xdst->u.dst;
|
||||
|
||||
memset(dst + 1, 0, sizeof(*xdst) - sizeof(*dst));
|
||||
xdst->flo.ops = &xfrm_bundle_fc_ops;
|
||||
} else
|
||||
xdst = ERR_PTR(-ENOBUFS);
|
||||
|
||||
@@ -2521,11 +2436,9 @@ static struct dst_entry *xfrm_dst_check(struct dst_entry *dst, u32 cookie)
|
||||
* notice. That's what we are validating here via the
|
||||
* stale_bundle() check.
|
||||
*
|
||||
* When an xdst is removed from flow cache, DST_OBSOLETE_DEAD will
|
||||
* be marked on it.
|
||||
* When a dst is removed from the fib tree, DST_OBSOLETE_DEAD will
|
||||
* be marked on it.
|
||||
* Both will force stable_bundle() to fail on any xdst bundle with
|
||||
* This will force stale_bundle() to fail on any xdst bundle with
|
||||
* this dst linked in it.
|
||||
*/
|
||||
if (dst->obsolete < 0 && !stale_bundle(dst))
|
||||
@@ -2565,18 +2478,6 @@ static struct dst_entry *xfrm_negative_advice(struct dst_entry *dst)
|
||||
return dst;
|
||||
}
|
||||
|
||||
void xfrm_garbage_collect(struct net *net)
|
||||
{
|
||||
flow_cache_flush(net);
|
||||
}
|
||||
EXPORT_SYMBOL(xfrm_garbage_collect);
|
||||
|
||||
void xfrm_garbage_collect_deferred(struct net *net)
|
||||
{
|
||||
flow_cache_flush_deferred(net);
|
||||
}
|
||||
EXPORT_SYMBOL(xfrm_garbage_collect_deferred);
|
||||
|
||||
static void xfrm_init_pmtu(struct dst_entry *dst)
|
||||
{
|
||||
do {
|
||||
@@ -2914,14 +2815,9 @@ static int __net_init xfrm_net_init(struct net *net)
|
||||
rv = xfrm_sysctl_init(net);
|
||||
if (rv < 0)
|
||||
goto out_sysctl;
|
||||
rv = flow_cache_init(net);
|
||||
if (rv < 0)
|
||||
goto out;
|
||||
|
||||
return 0;
|
||||
|
||||
out:
|
||||
xfrm_sysctl_fini(net);
|
||||
out_sysctl:
|
||||
xfrm_policy_fini(net);
|
||||
out_policy:
|
||||
@@ -2934,7 +2830,6 @@ out_statistics:
|
||||
|
||||
static void __net_exit xfrm_net_exit(struct net *net)
|
||||
{
|
||||
flow_cache_fini(net);
|
||||
xfrm_sysctl_fini(net);
|
||||
xfrm_policy_fini(net);
|
||||
xfrm_state_fini(net);
|
||||
@@ -2948,7 +2843,6 @@ static struct pernet_operations __net_initdata xfrm_net_ops = {
|
||||
|
||||
void __init xfrm_init(void)
|
||||
{
|
||||
flow_cache_hp_init();
|
||||
register_pernet_subsys(&xfrm_net_ops);
|
||||
seqcount_init(&xfrm_policy_hash_generation);
|
||||
xfrm_input_init();
|
||||
|
@@ -1815,8 +1815,6 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
|
||||
out:
|
||||
xfrm_pol_put(xp);
|
||||
if (delete && err == 0)
|
||||
xfrm_garbage_collect(net);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -2027,7 +2025,6 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
xfrm_garbage_collect(net);
|
||||
|
||||
c.data.type = type;
|
||||
c.event = nlh->nlmsg_type;
|
||||
|
Reference in New Issue
Block a user