aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@openvz.org>2008-04-24 04:02:16 -0400
committerDavid S. Miller <davem@davemloft.net>2008-04-24 04:02:16 -0400
commit5e659e4cb0eedacdc1f621a61e400a4611ddef8a (patch)
treefa3c8743010dd640c48584a6fa8a910d27350c01 /net/ipv4
parent3d36696024499aef19dbf24a781e91a24fbbe4af (diff)
[NET]: Fix heavy stack usage in seq_file output routines.
Plan C: we can follow the Al Viro's proposal about %n like in this patch. The same applies to udp, fib (the /proc/net/route file), rt_cache and sctp debug. This is minus ~150-200 bytes for each. Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/fib_hash.c17
-rw-r--r--net/ipv4/fib_trie.c18
-rw-r--r--net/ipv4/route.c11
-rw-r--r--net/ipv4/tcp_ipv4.c36
-rw-r--r--net/ipv4/udp.c15
5 files changed, 52 insertions, 45 deletions
diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c
index 02088deb046..2e2fc3376ac 100644
--- a/net/ipv4/fib_hash.c
+++ b/net/ipv4/fib_hash.c
@@ -1003,7 +1003,7 @@ static unsigned fib_flag_trans(int type, __be32 mask, struct fib_info *fi)
1003static int fib_seq_show(struct seq_file *seq, void *v) 1003static int fib_seq_show(struct seq_file *seq, void *v)
1004{ 1004{
1005 struct fib_iter_state *iter; 1005 struct fib_iter_state *iter;
1006 char bf[128]; 1006 int len;
1007 __be32 prefix, mask; 1007 __be32 prefix, mask;
1008 unsigned flags; 1008 unsigned flags;
1009 struct fib_node *f; 1009 struct fib_node *f;
@@ -1025,18 +1025,19 @@ static int fib_seq_show(struct seq_file *seq, void *v)
1025 mask = FZ_MASK(iter->zone); 1025 mask = FZ_MASK(iter->zone);
1026 flags = fib_flag_trans(fa->fa_type, mask, fi); 1026 flags = fib_flag_trans(fa->fa_type, mask, fi);
1027 if (fi) 1027 if (fi)
1028 snprintf(bf, sizeof(bf), 1028 seq_printf(seq,
1029 "%s\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u", 1029 "%s\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u%n",
1030 fi->fib_dev ? fi->fib_dev->name : "*", prefix, 1030 fi->fib_dev ? fi->fib_dev->name : "*", prefix,
1031 fi->fib_nh->nh_gw, flags, 0, 0, fi->fib_priority, 1031 fi->fib_nh->nh_gw, flags, 0, 0, fi->fib_priority,
1032 mask, (fi->fib_advmss ? fi->fib_advmss + 40 : 0), 1032 mask, (fi->fib_advmss ? fi->fib_advmss + 40 : 0),
1033 fi->fib_window, 1033 fi->fib_window,
1034 fi->fib_rtt >> 3); 1034 fi->fib_rtt >> 3, &len);
1035 else 1035 else
1036 snprintf(bf, sizeof(bf), 1036 seq_printf(seq,
1037 "*\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u", 1037 "*\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u%n",
1038 prefix, 0, flags, 0, 0, 0, mask, 0, 0, 0); 1038 prefix, 0, flags, 0, 0, 0, mask, 0, 0, 0, &len);
1039 seq_printf(seq, "%-127s\n", bf); 1039
1040 seq_printf(seq, "%*s\n", 127 - len, "");
1040out: 1041out:
1041 return 0; 1042 return 0;
1042} 1043}
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index ea294fffb9c..4b02d14e7ab 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -2602,15 +2602,16 @@ static int fib_route_seq_show(struct seq_file *seq, void *v)
2602 list_for_each_entry_rcu(fa, &li->falh, fa_list) { 2602 list_for_each_entry_rcu(fa, &li->falh, fa_list) {
2603 const struct fib_info *fi = fa->fa_info; 2603 const struct fib_info *fi = fa->fa_info;
2604 unsigned flags = fib_flag_trans(fa->fa_type, mask, fi); 2604 unsigned flags = fib_flag_trans(fa->fa_type, mask, fi);
2605 char bf[128]; 2605 int len;
2606 2606
2607 if (fa->fa_type == RTN_BROADCAST 2607 if (fa->fa_type == RTN_BROADCAST
2608 || fa->fa_type == RTN_MULTICAST) 2608 || fa->fa_type == RTN_MULTICAST)
2609 continue; 2609 continue;
2610 2610
2611 if (fi) 2611 if (fi)
2612 snprintf(bf, sizeof(bf), 2612 seq_printf(seq,
2613 "%s\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u", 2613 "%s\t%08X\t%08X\t%04X\t%d\t%u\t"
2614 "%d\t%08X\t%d\t%u\t%u%n",
2614 fi->fib_dev ? fi->fib_dev->name : "*", 2615 fi->fib_dev ? fi->fib_dev->name : "*",
2615 prefix, 2616 prefix,
2616 fi->fib_nh->nh_gw, flags, 0, 0, 2617 fi->fib_nh->nh_gw, flags, 0, 0,
@@ -2619,14 +2620,15 @@ static int fib_route_seq_show(struct seq_file *seq, void *v)
2619 (fi->fib_advmss ? 2620 (fi->fib_advmss ?
2620 fi->fib_advmss + 40 : 0), 2621 fi->fib_advmss + 40 : 0),
2621 fi->fib_window, 2622 fi->fib_window,
2622 fi->fib_rtt >> 3); 2623 fi->fib_rtt >> 3, &len);
2623 else 2624 else
2624 snprintf(bf, sizeof(bf), 2625 seq_printf(seq,
2625 "*\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u", 2626 "*\t%08X\t%08X\t%04X\t%d\t%u\t"
2627 "%d\t%08X\t%d\t%u\t%u%n",
2626 prefix, 0, flags, 0, 0, 0, 2628 prefix, 0, flags, 0, 0, 0,
2627 mask, 0, 0, 0); 2629 mask, 0, 0, 0, &len);
2628 2630
2629 seq_printf(seq, "%-127s\n", bf); 2631 seq_printf(seq, "%*s\n", 127 - len, "");
2630 } 2632 }
2631 } 2633 }
2632 2634
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 780e9484c82..ce25a13f343 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -367,10 +367,10 @@ static int rt_cache_seq_show(struct seq_file *seq, void *v)
367 "HHUptod\tSpecDst"); 367 "HHUptod\tSpecDst");
368 else { 368 else {
369 struct rtable *r = v; 369 struct rtable *r = v;
370 char temp[256]; 370 int len;
371 371
372 sprintf(temp, "%s\t%08lX\t%08lX\t%8X\t%d\t%u\t%d\t" 372 seq_printf(seq, "%s\t%08lX\t%08lX\t%8X\t%d\t%u\t%d\t"
373 "%08lX\t%d\t%u\t%u\t%02X\t%d\t%1d\t%08X", 373 "%08lX\t%d\t%u\t%u\t%02X\t%d\t%1d\t%08X%n",
374 r->u.dst.dev ? r->u.dst.dev->name : "*", 374 r->u.dst.dev ? r->u.dst.dev->name : "*",
375 (unsigned long)r->rt_dst, (unsigned long)r->rt_gateway, 375 (unsigned long)r->rt_dst, (unsigned long)r->rt_gateway,
376 r->rt_flags, atomic_read(&r->u.dst.__refcnt), 376 r->rt_flags, atomic_read(&r->u.dst.__refcnt),
@@ -384,8 +384,9 @@ static int rt_cache_seq_show(struct seq_file *seq, void *v)
384 r->u.dst.hh ? atomic_read(&r->u.dst.hh->hh_refcnt) : -1, 384 r->u.dst.hh ? atomic_read(&r->u.dst.hh->hh_refcnt) : -1,
385 r->u.dst.hh ? (r->u.dst.hh->hh_output == 385 r->u.dst.hh ? (r->u.dst.hh->hh_output ==
386 dev_queue_xmit) : 0, 386 dev_queue_xmit) : 0,
387 r->rt_spec_dst); 387 r->rt_spec_dst, &len);
388 seq_printf(seq, "%-127s\n", temp); 388
389 seq_printf(seq, "%*s\n", 127 - len, "");
389 } 390 }
390 return 0; 391 return 0;
391} 392}
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 776615180b9..0e9bc120707 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2255,13 +2255,13 @@ void tcp_proc_unregister(struct net *net, struct tcp_seq_afinfo *afinfo)
2255} 2255}
2256 2256
2257static void get_openreq4(struct sock *sk, struct request_sock *req, 2257static void get_openreq4(struct sock *sk, struct request_sock *req,
2258 char *tmpbuf, int i, int uid) 2258 struct seq_file *f, int i, int uid, int *len)
2259{ 2259{
2260 const struct inet_request_sock *ireq = inet_rsk(req); 2260 const struct inet_request_sock *ireq = inet_rsk(req);
2261 int ttd = req->expires - jiffies; 2261 int ttd = req->expires - jiffies;
2262 2262
2263 sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X" 2263 seq_printf(f, "%4d: %08X:%04X %08X:%04X"
2264 " %02X %08X:%08X %02X:%08lX %08X %5d %8d %u %d %p", 2264 " %02X %08X:%08X %02X:%08lX %08X %5d %8d %u %d %p%n",
2265 i, 2265 i,
2266 ireq->loc_addr, 2266 ireq->loc_addr,
2267 ntohs(inet_sk(sk)->sport), 2267 ntohs(inet_sk(sk)->sport),
@@ -2276,10 +2276,11 @@ static void get_openreq4(struct sock *sk, struct request_sock *req,
2276 0, /* non standard timer */ 2276 0, /* non standard timer */
2277 0, /* open_requests have no inode */ 2277 0, /* open_requests have no inode */
2278 atomic_read(&sk->sk_refcnt), 2278 atomic_read(&sk->sk_refcnt),
2279 req); 2279 req,
2280 len);
2280} 2281}
2281 2282
2282static void get_tcp4_sock(struct sock *sk, char *tmpbuf, int i) 2283static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len)
2283{ 2284{
2284 int timer_active; 2285 int timer_active;
2285 unsigned long timer_expires; 2286 unsigned long timer_expires;
@@ -2305,8 +2306,8 @@ static void get_tcp4_sock(struct sock *sk, char *tmpbuf, int i)
2305 timer_expires = jiffies; 2306 timer_expires = jiffies;
2306 } 2307 }
2307 2308
2308 sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX " 2309 seq_printf(f, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX "
2309 "%08X %5d %8d %lu %d %p %u %u %u %u %d", 2310 "%08X %5d %8d %lu %d %p %u %u %u %u %d%n",
2310 i, src, srcp, dest, destp, sk->sk_state, 2311 i, src, srcp, dest, destp, sk->sk_state,
2311 tp->write_seq - tp->snd_una, 2312 tp->write_seq - tp->snd_una,
2312 sk->sk_state == TCP_LISTEN ? sk->sk_ack_backlog : 2313 sk->sk_state == TCP_LISTEN ? sk->sk_ack_backlog :
@@ -2322,11 +2323,12 @@ static void get_tcp4_sock(struct sock *sk, char *tmpbuf, int i)
2322 icsk->icsk_ack.ato, 2323 icsk->icsk_ack.ato,
2323 (icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong, 2324 (icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong,
2324 tp->snd_cwnd, 2325 tp->snd_cwnd,
2325 tp->snd_ssthresh >= 0xFFFF ? -1 : tp->snd_ssthresh); 2326 tp->snd_ssthresh >= 0xFFFF ? -1 : tp->snd_ssthresh,
2327 len);
2326} 2328}
2327 2329
2328static void get_timewait4_sock(struct inet_timewait_sock *tw, 2330static void get_timewait4_sock(struct inet_timewait_sock *tw,
2329 char *tmpbuf, int i) 2331 struct seq_file *f, int i, int *len)
2330{ 2332{
2331 __be32 dest, src; 2333 __be32 dest, src;
2332 __u16 destp, srcp; 2334 __u16 destp, srcp;
@@ -2340,11 +2342,11 @@ static void get_timewait4_sock(struct inet_timewait_sock *tw,
2340 destp = ntohs(tw->tw_dport); 2342 destp = ntohs(tw->tw_dport);
2341 srcp = ntohs(tw->tw_sport); 2343 srcp = ntohs(tw->tw_sport);
2342 2344
2343 sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X" 2345 seq_printf(f, "%4d: %08X:%04X %08X:%04X"
2344 " %02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %p", 2346 " %02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %p%n",
2345 i, src, srcp, dest, destp, tw->tw_substate, 0, 0, 2347 i, src, srcp, dest, destp, tw->tw_substate, 0, 0,
2346 3, jiffies_to_clock_t(ttd), 0, 0, 0, 0, 2348 3, jiffies_to_clock_t(ttd), 0, 0, 0, 0,
2347 atomic_read(&tw->tw_refcnt), tw); 2349 atomic_read(&tw->tw_refcnt), tw, len);
2348} 2350}
2349 2351
2350#define TMPSZ 150 2352#define TMPSZ 150
@@ -2352,7 +2354,7 @@ static void get_timewait4_sock(struct inet_timewait_sock *tw,
2352static int tcp4_seq_show(struct seq_file *seq, void *v) 2354static int tcp4_seq_show(struct seq_file *seq, void *v)
2353{ 2355{
2354 struct tcp_iter_state* st; 2356 struct tcp_iter_state* st;
2355 char tmpbuf[TMPSZ + 1]; 2357 int len;
2356 2358
2357 if (v == SEQ_START_TOKEN) { 2359 if (v == SEQ_START_TOKEN) {
2358 seq_printf(seq, "%-*s\n", TMPSZ - 1, 2360 seq_printf(seq, "%-*s\n", TMPSZ - 1,
@@ -2366,16 +2368,16 @@ static int tcp4_seq_show(struct seq_file *seq, void *v)
2366 switch (st->state) { 2368 switch (st->state) {
2367 case TCP_SEQ_STATE_LISTENING: 2369 case TCP_SEQ_STATE_LISTENING:
2368 case TCP_SEQ_STATE_ESTABLISHED: 2370 case TCP_SEQ_STATE_ESTABLISHED:
2369 get_tcp4_sock(v, tmpbuf, st->num); 2371 get_tcp4_sock(v, seq, st->num, &len);
2370 break; 2372 break;
2371 case TCP_SEQ_STATE_OPENREQ: 2373 case TCP_SEQ_STATE_OPENREQ:
2372 get_openreq4(st->syn_wait_sk, v, tmpbuf, st->num, st->uid); 2374 get_openreq4(st->syn_wait_sk, v, seq, st->num, st->uid, &len);
2373 break; 2375 break;
2374 case TCP_SEQ_STATE_TIME_WAIT: 2376 case TCP_SEQ_STATE_TIME_WAIT:
2375 get_timewait4_sock(v, tmpbuf, st->num); 2377 get_timewait4_sock(v, seq, st->num, &len);
2376 break; 2378 break;
2377 } 2379 }
2378 seq_printf(seq, "%-*s\n", TMPSZ - 1, tmpbuf); 2380 seq_printf(seq, "%*s\n", TMPSZ - 1 - len, "");
2379out: 2381out:
2380 return 0; 2382 return 0;
2381} 2383}
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index b053ac79527..1f535e31518 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1619,7 +1619,8 @@ void udp_proc_unregister(struct net *net, struct udp_seq_afinfo *afinfo)
1619} 1619}
1620 1620
1621/* ------------------------------------------------------------------------ */ 1621/* ------------------------------------------------------------------------ */
1622static void udp4_format_sock(struct sock *sp, char *tmpbuf, int bucket) 1622static void udp4_format_sock(struct sock *sp, struct seq_file *f,
1623 int bucket, int *len)
1623{ 1624{
1624 struct inet_sock *inet = inet_sk(sp); 1625 struct inet_sock *inet = inet_sk(sp);
1625 __be32 dest = inet->daddr; 1626 __be32 dest = inet->daddr;
@@ -1627,13 +1628,13 @@ static void udp4_format_sock(struct sock *sp, char *tmpbuf, int bucket)
1627 __u16 destp = ntohs(inet->dport); 1628 __u16 destp = ntohs(inet->dport);
1628 __u16 srcp = ntohs(inet->sport); 1629 __u16 srcp = ntohs(inet->sport);
1629 1630
1630 sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X" 1631 seq_printf(f, "%4d: %08X:%04X %08X:%04X"
1631 " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p", 1632 " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p%n",
1632 bucket, src, srcp, dest, destp, sp->sk_state, 1633 bucket, src, srcp, dest, destp, sp->sk_state,
1633 atomic_read(&sp->sk_wmem_alloc), 1634 atomic_read(&sp->sk_wmem_alloc),
1634 atomic_read(&sp->sk_rmem_alloc), 1635 atomic_read(&sp->sk_rmem_alloc),
1635 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp), 1636 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp),
1636 atomic_read(&sp->sk_refcnt), sp); 1637 atomic_read(&sp->sk_refcnt), sp, len);
1637} 1638}
1638 1639
1639int udp4_seq_show(struct seq_file *seq, void *v) 1640int udp4_seq_show(struct seq_file *seq, void *v)
@@ -1644,11 +1645,11 @@ int udp4_seq_show(struct seq_file *seq, void *v)
1644 "rx_queue tr tm->when retrnsmt uid timeout " 1645 "rx_queue tr tm->when retrnsmt uid timeout "
1645 "inode"); 1646 "inode");
1646 else { 1647 else {
1647 char tmpbuf[129];
1648 struct udp_iter_state *state = seq->private; 1648 struct udp_iter_state *state = seq->private;
1649 int len;
1649 1650
1650 udp4_format_sock(v, tmpbuf, state->bucket); 1651 udp4_format_sock(v, seq, state->bucket, &len);
1651 seq_printf(seq, "%-127s\n", tmpbuf); 1652 seq_printf(seq, "%*s\n", 127 - len ,"");
1652 } 1653 }
1653 return 0; 1654 return 0;
1654} 1655}