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>
This commit is contained in:
parent
f8e9881c2a
commit
66944e1c57
1 changed files with 7 additions and 6 deletions
|
@ -354,7 +354,8 @@ static void inetpeer_free_rcu(struct rcu_head *head)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* May be called with local BH enabled. */
|
/* May be called with local BH enabled. */
|
||||||
static void unlink_from_pool(struct inet_peer *p, struct inet_peer_base *base)
|
static void unlink_from_pool(struct inet_peer *p, struct inet_peer_base *base,
|
||||||
|
struct inet_peer __rcu **stack[PEER_MAXDEPTH])
|
||||||
{
|
{
|
||||||
int do_free;
|
int do_free;
|
||||||
|
|
||||||
|
@ -368,7 +369,6 @@ static void unlink_from_pool(struct inet_peer *p, struct inet_peer_base *base)
|
||||||
* We use refcnt=-1 to alert lockless readers this entry is deleted.
|
* We use refcnt=-1 to alert lockless readers this entry is deleted.
|
||||||
*/
|
*/
|
||||||
if (atomic_cmpxchg(&p->refcnt, 1, -1) == 1) {
|
if (atomic_cmpxchg(&p->refcnt, 1, -1) == 1) {
|
||||||
struct inet_peer __rcu **stack[PEER_MAXDEPTH];
|
|
||||||
struct inet_peer __rcu ***stackptr, ***delp;
|
struct inet_peer __rcu ***stackptr, ***delp;
|
||||||
if (lookup(&p->daddr, stack, base) != p)
|
if (lookup(&p->daddr, stack, base) != p)
|
||||||
BUG();
|
BUG();
|
||||||
|
@ -422,7 +422,7 @@ static struct inet_peer_base *peer_to_base(struct inet_peer *p)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* May be called with local BH enabled. */
|
/* May be called with local BH enabled. */
|
||||||
static int cleanup_once(unsigned long ttl)
|
static int cleanup_once(unsigned long ttl, struct inet_peer __rcu **stack[PEER_MAXDEPTH])
|
||||||
{
|
{
|
||||||
struct inet_peer *p = NULL;
|
struct inet_peer *p = NULL;
|
||||||
|
|
||||||
|
@ -454,7 +454,7 @@ static int cleanup_once(unsigned long ttl)
|
||||||
* happen because of entry limits in route cache. */
|
* happen because of entry limits in route cache. */
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
unlink_from_pool(p, peer_to_base(p));
|
unlink_from_pool(p, peer_to_base(p), stack);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -524,7 +524,7 @@ struct inet_peer *inet_getpeer(struct inetpeer_addr *daddr, int create)
|
||||||
|
|
||||||
if (base->total >= inet_peer_threshold)
|
if (base->total >= inet_peer_threshold)
|
||||||
/* Remove one less-recently-used entry. */
|
/* Remove one less-recently-used entry. */
|
||||||
cleanup_once(0);
|
cleanup_once(0, stack);
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
@ -540,6 +540,7 @@ static void peer_check_expire(unsigned long dummy)
|
||||||
{
|
{
|
||||||
unsigned long now = jiffies;
|
unsigned long now = jiffies;
|
||||||
int ttl, total;
|
int ttl, total;
|
||||||
|
struct inet_peer __rcu **stack[PEER_MAXDEPTH];
|
||||||
|
|
||||||
total = compute_total();
|
total = compute_total();
|
||||||
if (total >= inet_peer_threshold)
|
if (total >= inet_peer_threshold)
|
||||||
|
@ -548,7 +549,7 @@ static void peer_check_expire(unsigned long dummy)
|
||||||
ttl = inet_peer_maxttl
|
ttl = inet_peer_maxttl
|
||||||
- (inet_peer_maxttl - inet_peer_minttl) / HZ *
|
- (inet_peer_maxttl - inet_peer_minttl) / HZ *
|
||||||
total / inet_peer_threshold * HZ;
|
total / inet_peer_threshold * HZ;
|
||||||
while (!cleanup_once(ttl)) {
|
while (!cleanup_once(ttl, stack)) {
|
||||||
if (jiffies != now)
|
if (jiffies != now)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue