diff options
author | Jamal Hadi Salim <hadi@cyberus.ca> | 2006-12-04 20:02:37 -0800 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-12-06 18:38:44 -0800 |
commit | baf5d743d1b8783fdbd5c1260ada2926e5bbaaee (patch) | |
tree | 1dba3ae8d7e40a9b4f6ccb886d1cb511396e5381 /net/xfrm/xfrm_policy.c | |
parent | 1b6651f1bf2453d593478aa88af267f057fd73e2 (diff) | |
download | kernel_samsung_smdk4412-baf5d743d1b8783fdbd5c1260ada2926e5bbaaee.zip kernel_samsung_smdk4412-baf5d743d1b8783fdbd5c1260ada2926e5bbaaee.tar.gz kernel_samsung_smdk4412-baf5d743d1b8783fdbd5c1260ada2926e5bbaaee.tar.bz2 |
[XFRM] Optimize policy dumping
This change optimizes the dumping of Security policies.
1) Before this change ..
speedopolis:~# time ./ip xf pol
real 0m22.274s
user 0m0.000s
sys 0m22.269s
2) Turn off sub-policies
speedopolis:~# ./ip xf pol
real 0m13.496s
user 0m0.000s
sys 0m13.493s
i suppose the above is to be expected
3) With this change ..
speedopolis:~# time ./ip x policy
real 0m7.901s
user 0m0.008s
sys 0m7.896s
Diffstat (limited to 'net/xfrm/xfrm_policy.c')
-rw-r--r-- | net/xfrm/xfrm_policy.c | 55 |
1 files changed, 25 insertions, 30 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index f6c77bd..4f04222 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -860,33 +860,12 @@ EXPORT_SYMBOL(xfrm_policy_flush); int xfrm_policy_walk(u8 type, int (*func)(struct xfrm_policy *, int, int, void*), void *data) { - struct xfrm_policy *pol; + struct xfrm_policy *pol, *last = NULL; struct hlist_node *entry; - int dir, count, error; + int dir, last_dir = 0, count, error; read_lock_bh(&xfrm_policy_lock); count = 0; - for (dir = 0; dir < 2*XFRM_POLICY_MAX; dir++) { - struct hlist_head *table = xfrm_policy_bydst[dir].table; - int i; - - hlist_for_each_entry(pol, entry, - &xfrm_policy_inexact[dir], bydst) { - if (pol->type == type) - count++; - } - for (i = xfrm_policy_bydst[dir].hmask; i >= 0; i--) { - hlist_for_each_entry(pol, entry, table + i, bydst) { - if (pol->type == type) - count++; - } - } - } - - if (count == 0) { - error = -ENOENT; - goto out; - } for (dir = 0; dir < 2*XFRM_POLICY_MAX; dir++) { struct hlist_head *table = xfrm_policy_bydst[dir].table; @@ -896,21 +875,37 @@ int xfrm_policy_walk(u8 type, int (*func)(struct xfrm_policy *, int, int, void*) &xfrm_policy_inexact[dir], bydst) { if (pol->type != type) continue; - error = func(pol, dir % XFRM_POLICY_MAX, --count, data); - if (error) - goto out; + if (last) { + error = func(last, last_dir % XFRM_POLICY_MAX, + count, data); + if (error) + goto out; + } + last = pol; + last_dir = dir; + count++; } for (i = xfrm_policy_bydst[dir].hmask; i >= 0; i--) { hlist_for_each_entry(pol, entry, table + i, bydst) { if (pol->type != type) continue; - error = func(pol, dir % XFRM_POLICY_MAX, --count, data); - if (error) - goto out; + if (last) { + error = func(last, last_dir % XFRM_POLICY_MAX, + count, data); + if (error) + goto out; + } + last = pol; + last_dir = dir; + count++; } } } - error = 0; + if (count == 0) { + error = -ENOENT; + goto out; + } + error = func(last, last_dir % XFRM_POLICY_MAX, 0, data); out: read_unlock_bh(&xfrm_policy_lock); return error; |