diff options
author | Jamal Hadi Salim <hadi@cyberus.ca> | 2006-12-04 20:03:35 -0800 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-12-06 18:38:45 -0800 |
commit | 94b9bb5480e73cec4552b19fc3f809742b4ebf67 (patch) | |
tree | ac0186acb0edcae0ee0d134b5bf816513d0d440a /net | |
parent | baf5d743d1b8783fdbd5c1260ada2926e5bbaaee (diff) | |
download | linux-94b9bb5480e73cec4552b19fc3f809742b4ebf67.tar.gz linux-94b9bb5480e73cec4552b19fc3f809742b4ebf67.tar.bz2 linux-94b9bb5480e73cec4552b19fc3f809742b4ebf67.zip |
[XFRM] Optimize SA dumping
Same comments as in "[XFRM] Optimize policy dumping"
The numbers are (20K SAs):
Diffstat (limited to 'net')
-rw-r--r-- | net/xfrm/xfrm_state.c | 24 |
1 files changed, 11 insertions, 13 deletions
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index da54a64ccfa3..a14c88bf17f0 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -1099,7 +1099,7 @@ int xfrm_state_walk(u8 proto, int (*func)(struct xfrm_state *, int, void*), void *data) { int i; - struct xfrm_state *x; + struct xfrm_state *x, *last = NULL; struct hlist_node *entry; int count = 0; int err = 0; @@ -1107,24 +1107,22 @@ int xfrm_state_walk(u8 proto, int (*func)(struct xfrm_state *, int, void*), spin_lock_bh(&xfrm_state_lock); for (i = 0; i <= xfrm_state_hmask; i++) { hlist_for_each_entry(x, entry, xfrm_state_bydst+i, bydst) { - if (xfrm_id_proto_match(x->id.proto, proto)) - count++; + if (!xfrm_id_proto_match(x->id.proto, proto)) + continue; + if (last) { + err = func(last, count, data); + if (err) + goto out; + } + last = x; + count++; } } if (count == 0) { err = -ENOENT; goto out; } - - for (i = 0; i <= xfrm_state_hmask; i++) { - hlist_for_each_entry(x, entry, xfrm_state_bydst+i, bydst) { - if (!xfrm_id_proto_match(x->id.proto, proto)) - continue; - err = func(x, --count, data); - if (err) - goto out; - } - } + err = func(last, 0, data); out: spin_unlock_bh(&xfrm_state_lock); return err; |