diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2011-04-11 18:39:40 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-04-12 16:58:33 -0400 |
commit | 66944e1c5797562cebe2d1857d46dff60bf9a69e (patch) | |
tree | 8e7ff0099a1298daa15286788c2bfc7f395e3d74 /net/ipv4/inetpeer.c | |
parent | f8e9881c2aef1e982e5abc25c046820cd0b7cf64 (diff) |
inetpeer: reduce stack usage
On 64bit arches, we use 752 bytes of stack when cleanup_once() is called
from inet_getpeer().
Lets share the avl stack to save ~376 bytes.
Before patch :
# objdump -d net/ipv4/inetpeer.o | scripts/checkstack.pl
0x000006c3 unlink_from_pool [inetpeer.o]: 376
0x00000721 unlink_from_pool [inetpeer.o]: 376
0x00000cb1 inet_getpeer [inetpeer.o]: 376
0x00000e6d inet_getpeer [inetpeer.o]: 376
0x0004 inet_initpeers [inetpeer.o]: 112
# size net/ipv4/inetpeer.o
text data bss dec hex filename
5320 432 21 5773 168d net/ipv4/inetpeer.o
After patch :
objdump -d net/ipv4/inetpeer.o | scripts/checkstack.pl
0x00000c11 inet_getpeer [inetpeer.o]: 376
0x00000dcd inet_getpeer [inetpeer.o]: 376
0x00000ab9 peer_check_expire [inetpeer.o]: 328
0x00000b7f peer_check_expire [inetpeer.o]: 328
0x0004 inet_initpeers [inetpeer.o]: 112
# size net/ipv4/inetpeer.o
text data bss dec hex filename
5163 432 21 5616 15f0 net/ipv4/inetpeer.o
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Scot Doyle <lkml@scotdoyle.com>
Cc: Stephen Hemminger <shemminger@vyatta.com>
Cc: Hiroaki SHIMODA <shimoda.hiroaki@gmail.com>
Reviewed-by: Hiroaki SHIMODA <shimoda.hiroaki@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/inetpeer.c')
-rw-r--r-- | net/ipv4/inetpeer.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index dd1b20eca1a2..9df4e635fb5f 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c | |||
@@ -354,7 +354,8 @@ static void inetpeer_free_rcu(struct rcu_head *head) | |||
354 | } | 354 | } |
355 | 355 | ||
356 | /* May be called with local BH enabled. */ | 356 | /* May be called with local BH enabled. */ |
357 | static void unlink_from_pool(struct inet_peer *p, struct inet_peer_base *base) | 357 | static void unlink_from_pool(struct inet_peer *p, struct inet_peer_base *base, |
358 | struct inet_peer __rcu **stack[PEER_MAXDEPTH]) | ||
358 | { | 359 | { |
359 | int do_free; | 360 | int do_free; |
360 | 361 | ||
@@ -368,7 +369,6 @@ static void unlink_from_pool(struct inet_peer *p, struct inet_peer_base *base) | |||
368 | * We use refcnt=-1 to alert lockless readers this entry is deleted. | 369 | * We use refcnt=-1 to alert lockless readers this entry is deleted. |
369 | */ | 370 | */ |
370 | if (atomic_cmpxchg(&p->refcnt, 1, -1) == 1) { | 371 | if (atomic_cmpxchg(&p->refcnt, 1, -1) == 1) { |
371 | struct inet_peer __rcu **stack[PEER_MAXDEPTH]; | ||
372 | struct inet_peer __rcu ***stackptr, ***delp; | 372 | struct inet_peer __rcu ***stackptr, ***delp; |
373 | if (lookup(&p->daddr, stack, base) != p) | 373 | if (lookup(&p->daddr, stack, base) != p) |
374 | BUG(); | 374 | BUG(); |
@@ -422,7 +422,7 @@ static struct inet_peer_base *peer_to_base(struct inet_peer *p) | |||
422 | } | 422 | } |
423 | 423 | ||
424 | /* May be called with local BH enabled. */ | 424 | /* May be called with local BH enabled. */ |
425 | static int cleanup_once(unsigned long ttl) | 425 | static int cleanup_once(unsigned long ttl, struct inet_peer __rcu **stack[PEER_MAXDEPTH]) |
426 | { | 426 | { |
427 | struct inet_peer *p = NULL; | 427 | struct inet_peer *p = NULL; |
428 | 428 | ||
@@ -454,7 +454,7 @@ static int cleanup_once(unsigned long ttl) | |||
454 | * happen because of entry limits in route cache. */ | 454 | * happen because of entry limits in route cache. */ |
455 | return -1; | 455 | return -1; |
456 | 456 | ||
457 | unlink_from_pool(p, peer_to_base(p)); | 457 | unlink_from_pool(p, peer_to_base(p), stack); |
458 | return 0; | 458 | return 0; |
459 | } | 459 | } |
460 | 460 | ||
@@ -524,7 +524,7 @@ struct inet_peer *inet_getpeer(struct inetpeer_addr *daddr, int create) | |||
524 | 524 | ||
525 | if (base->total >= inet_peer_threshold) | 525 | if (base->total >= inet_peer_threshold) |
526 | /* Remove one less-recently-used entry. */ | 526 | /* Remove one less-recently-used entry. */ |
527 | cleanup_once(0); | 527 | cleanup_once(0, stack); |
528 | 528 | ||
529 | return p; | 529 | return p; |
530 | } | 530 | } |
@@ -540,6 +540,7 @@ static void peer_check_expire(unsigned long dummy) | |||
540 | { | 540 | { |
541 | unsigned long now = jiffies; | 541 | unsigned long now = jiffies; |
542 | int ttl, total; | 542 | int ttl, total; |
543 | struct inet_peer __rcu **stack[PEER_MAXDEPTH]; | ||
543 | 544 | ||
544 | total = compute_total(); | 545 | total = compute_total(); |
545 | if (total >= inet_peer_threshold) | 546 | if (total >= inet_peer_threshold) |
@@ -548,7 +549,7 @@ static void peer_check_expire(unsigned long dummy) | |||
548 | ttl = inet_peer_maxttl | 549 | ttl = inet_peer_maxttl |
549 | - (inet_peer_maxttl - inet_peer_minttl) / HZ * | 550 | - (inet_peer_maxttl - inet_peer_minttl) / HZ * |
550 | total / inet_peer_threshold * HZ; | 551 | total / inet_peer_threshold * HZ; |
551 | while (!cleanup_once(ttl)) { | 552 | while (!cleanup_once(ttl, stack)) { |
552 | if (jiffies != now) | 553 | if (jiffies != now) |
553 | break; | 554 | break; |
554 | } | 555 | } |