diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2010-10-08 02:37:34 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-10-11 16:06:53 -0400 |
commit | fc66f95c68b6d4535a0ea2ea15d5cf626e310956 (patch) | |
tree | ac3a7f08ad741a67ff683bf93e5669ddcae95ed7 /net/core | |
parent | 0ed8ddf4045fcfcac36bad753dc4046118c603ec (diff) |
net dst: use a percpu_counter to track entries
struct dst_ops tracks number of allocated dst in an atomic_t field,
subject to high cache line contention in stress workload.
Switch to a percpu_counter, to reduce number of time we need to dirty a
central location. Place it on a separate cache line to avoid dirtying
read only fields.
Stress test :
(Sending 160.000.000 UDP frames,
IP route cache disabled, dual E5540 @2.53GHz,
32bit kernel, FIB_TRIE, SLUB/NUMA)
Before:
real 0m51.179s
user 0m15.329s
sys 10m15.942s
After:
real 0m45.570s
user 0m15.525s
sys 9m56.669s
With a small reordering of struct neighbour fields, subject of a
following patch, (to separate refcnt from other read mostly fields)
real 0m41.841s
user 0m15.261s
sys 8m45.949s
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/dst.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/net/core/dst.c b/net/core/dst.c index 978a1ee1f7d0..32e542d7f472 100644 --- a/net/core/dst.c +++ b/net/core/dst.c | |||
@@ -168,7 +168,7 @@ void *dst_alloc(struct dst_ops *ops) | |||
168 | { | 168 | { |
169 | struct dst_entry *dst; | 169 | struct dst_entry *dst; |
170 | 170 | ||
171 | if (ops->gc && atomic_read(&ops->entries) > ops->gc_thresh) { | 171 | if (ops->gc && dst_entries_get_fast(ops) > ops->gc_thresh) { |
172 | if (ops->gc(ops)) | 172 | if (ops->gc(ops)) |
173 | return NULL; | 173 | return NULL; |
174 | } | 174 | } |
@@ -183,7 +183,7 @@ void *dst_alloc(struct dst_ops *ops) | |||
183 | #if RT_CACHE_DEBUG >= 2 | 183 | #if RT_CACHE_DEBUG >= 2 |
184 | atomic_inc(&dst_total); | 184 | atomic_inc(&dst_total); |
185 | #endif | 185 | #endif |
186 | atomic_inc(&ops->entries); | 186 | dst_entries_add(ops, 1); |
187 | return dst; | 187 | return dst; |
188 | } | 188 | } |
189 | EXPORT_SYMBOL(dst_alloc); | 189 | EXPORT_SYMBOL(dst_alloc); |
@@ -236,7 +236,7 @@ again: | |||
236 | neigh_release(neigh); | 236 | neigh_release(neigh); |
237 | } | 237 | } |
238 | 238 | ||
239 | atomic_dec(&dst->ops->entries); | 239 | dst_entries_add(dst->ops, -1); |
240 | 240 | ||
241 | if (dst->ops->destroy) | 241 | if (dst->ops->destroy) |
242 | dst->ops->destroy(dst); | 242 | dst->ops->destroy(dst); |