Commit 5e659e4cb0eedacdc1f621a61e400a4611ddef8a

Authored by Pavel Emelyanov
Committed by David S. Miller
1 parent 3d36696024

[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>

Showing 6 changed files with 56 additions and 50 deletions Side-by-side Diff

... ... @@ -1003,7 +1003,7 @@
1003 1003 static int fib_seq_show(struct seq_file *seq, void *v)
1004 1004 {
1005 1005 struct fib_iter_state *iter;
1006   - char bf[128];
  1006 + int len;
1007 1007 __be32 prefix, mask;
1008 1008 unsigned flags;
1009 1009 struct fib_node *f;
1010 1010  
1011 1011  
... ... @@ -1025,18 +1025,19 @@
1025 1025 mask = FZ_MASK(iter->zone);
1026 1026 flags = fib_flag_trans(fa->fa_type, mask, fi);
1027 1027 if (fi)
1028   - snprintf(bf, sizeof(bf),
1029   - "%s\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u",
  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%n",
1030 1030 fi->fib_dev ? fi->fib_dev->name : "*", prefix,
1031 1031 fi->fib_nh->nh_gw, flags, 0, 0, fi->fib_priority,
1032 1032 mask, (fi->fib_advmss ? fi->fib_advmss + 40 : 0),
1033 1033 fi->fib_window,
1034   - fi->fib_rtt >> 3);
  1034 + fi->fib_rtt >> 3, &len);
1035 1035 else
1036   - snprintf(bf, sizeof(bf),
1037   - "*\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u",
1038   - prefix, 0, flags, 0, 0, 0, mask, 0, 0, 0);
1039   - seq_printf(seq, "%-127s\n", 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%n",
  1038 + prefix, 0, flags, 0, 0, 0, mask, 0, 0, 0, &len);
  1039 +
  1040 + seq_printf(seq, "%*s\n", 127 - len, "");
1040 1041 out:
1041 1042 return 0;
1042 1043 }
... ... @@ -2602,15 +2602,16 @@
2602 2602 list_for_each_entry_rcu(fa, &li->falh, fa_list) {
2603 2603 const struct fib_info *fi = fa->fa_info;
2604 2604 unsigned flags = fib_flag_trans(fa->fa_type, mask, fi);
2605   - char bf[128];
  2605 + int len;
2606 2606  
2607 2607 if (fa->fa_type == RTN_BROADCAST
2608 2608 || fa->fa_type == RTN_MULTICAST)
2609 2609 continue;
2610 2610  
2611 2611 if (fi)
2612   - snprintf(bf, sizeof(bf),
2613   - "%s\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u",
  2612 + seq_printf(seq,
  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 2615 fi->fib_dev ? fi->fib_dev->name : "*",
2615 2616 prefix,
2616 2617 fi->fib_nh->nh_gw, flags, 0, 0,
2617 2618  
2618 2619  
2619 2620  
... ... @@ -2619,14 +2620,15 @@
2619 2620 (fi->fib_advmss ?
2620 2621 fi->fib_advmss + 40 : 0),
2621 2622 fi->fib_window,
2622   - fi->fib_rtt >> 3);
  2623 + fi->fib_rtt >> 3, &len);
2623 2624 else
2624   - snprintf(bf, sizeof(bf),
2625   - "*\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u",
  2625 + seq_printf(seq,
  2626 + "*\t%08X\t%08X\t%04X\t%d\t%u\t"
  2627 + "%d\t%08X\t%d\t%u\t%u%n",
2626 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  
... ... @@ -367,10 +367,10 @@
367 367 "HHUptod\tSpecDst");
368 368 else {
369 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"
373   - "%08lX\t%d\t%u\t%u\t%02X\t%d\t%1d\t%08X",
  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%n",
374 374 r->u.dst.dev ? r->u.dst.dev->name : "*",
375 375 (unsigned long)r->rt_dst, (unsigned long)r->rt_gateway,
376 376 r->rt_flags, atomic_read(&r->u.dst.__refcnt),
... ... @@ -384,8 +384,9 @@
384 384 r->u.dst.hh ? atomic_read(&r->u.dst.hh->hh_refcnt) : -1,
385 385 r->u.dst.hh ? (r->u.dst.hh->hh_output ==
386 386 dev_queue_xmit) : 0,
387   - r->rt_spec_dst);
388   - seq_printf(seq, "%-127s\n", temp);
  387 + r->rt_spec_dst, &len);
  388 +
  389 + seq_printf(seq, "%*s\n", 127 - len, "");
389 390 }
390 391 return 0;
391 392 }
... ... @@ -2255,13 +2255,13 @@
2255 2255 }
2256 2256  
2257 2257 static 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 2260 const struct inet_request_sock *ireq = inet_rsk(req);
2261 2261 int ttd = req->expires - jiffies;
2262 2262  
2263   - sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
2264   - " %02X %08X:%08X %02X:%08lX %08X %5d %8d %u %d %p",
  2263 + seq_printf(f, "%4d: %08X:%04X %08X:%04X"
  2264 + " %02X %08X:%08X %02X:%08lX %08X %5d %8d %u %d %p%n",
2265 2265 i,
2266 2266 ireq->loc_addr,
2267 2267 ntohs(inet_sk(sk)->sport),
2268 2268  
... ... @@ -2276,10 +2276,11 @@
2276 2276 0, /* non standard timer */
2277 2277 0, /* open_requests have no inode */
2278 2278 atomic_read(&sk->sk_refcnt),
2279   - req);
  2279 + req,
  2280 + len);
2280 2281 }
2281 2282  
2282   -static void get_tcp4_sock(struct sock *sk, char *tmpbuf, int i)
  2283 +static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len)
2283 2284 {
2284 2285 int timer_active;
2285 2286 unsigned long timer_expires;
... ... @@ -2305,8 +2306,8 @@
2305 2306 timer_expires = jiffies;
2306 2307 }
2307 2308  
2308   - sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX "
2309   - "%08X %5d %8d %lu %d %p %u %u %u %u %d",
  2309 + seq_printf(f, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX "
  2310 + "%08X %5d %8d %lu %d %p %u %u %u %u %d%n",
2310 2311 i, src, srcp, dest, destp, sk->sk_state,
2311 2312 tp->write_seq - tp->snd_una,
2312 2313 sk->sk_state == TCP_LISTEN ? sk->sk_ack_backlog :
2313 2314  
... ... @@ -2322,11 +2323,12 @@
2322 2323 icsk->icsk_ack.ato,
2323 2324 (icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong,
2324 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  
2328 2330 static 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 2333 __be32 dest, src;
2332 2334 __u16 destp, srcp;
2333 2335  
... ... @@ -2340,11 +2342,11 @@
2340 2342 destp = ntohs(tw->tw_dport);
2341 2343 srcp = ntohs(tw->tw_sport);
2342 2344  
2343   - sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
2344   - " %02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %p",
  2345 + seq_printf(f, "%4d: %08X:%04X %08X:%04X"
  2346 + " %02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %p%n",
2345 2347 i, src, srcp, dest, destp, tw->tw_substate, 0, 0,
2346 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 2352 #define TMPSZ 150
... ... @@ -2352,7 +2354,7 @@
2352 2354 static int tcp4_seq_show(struct seq_file *seq, void *v)
2353 2355 {
2354 2356 struct tcp_iter_state* st;
2355   - char tmpbuf[TMPSZ + 1];
  2357 + int len;
2356 2358  
2357 2359 if (v == SEQ_START_TOKEN) {
2358 2360 seq_printf(seq, "%-*s\n", TMPSZ - 1,
2359 2361  
2360 2362  
2361 2363  
... ... @@ -2366,16 +2368,16 @@
2366 2368 switch (st->state) {
2367 2369 case TCP_SEQ_STATE_LISTENING:
2368 2370 case TCP_SEQ_STATE_ESTABLISHED:
2369   - get_tcp4_sock(v, tmpbuf, st->num);
  2371 + get_tcp4_sock(v, seq, st->num, &len);
2370 2372 break;
2371 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 2375 break;
2374 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 2378 break;
2377 2379 }
2378   - seq_printf(seq, "%-*s\n", TMPSZ - 1, tmpbuf);
  2380 + seq_printf(seq, "%*s\n", TMPSZ - 1 - len, "");
2379 2381 out:
2380 2382 return 0;
2381 2383 }
... ... @@ -1619,7 +1619,8 @@
1619 1619 }
1620 1620  
1621 1621 /* ------------------------------------------------------------------------ */
1622   -static void udp4_format_sock(struct sock *sp, char *tmpbuf, int bucket)
  1622 +static void udp4_format_sock(struct sock *sp, struct seq_file *f,
  1623 + int bucket, int *len)
1623 1624 {
1624 1625 struct inet_sock *inet = inet_sk(sp);
1625 1626 __be32 dest = inet->daddr;
1626 1627  
... ... @@ -1627,13 +1628,13 @@
1627 1628 __u16 destp = ntohs(inet->dport);
1628 1629 __u16 srcp = ntohs(inet->sport);
1629 1630  
1630   - sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
1631   - " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p",
  1631 + seq_printf(f, "%4d: %08X:%04X %08X:%04X"
  1632 + " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p%n",
1632 1633 bucket, src, srcp, dest, destp, sp->sk_state,
1633 1634 atomic_read(&sp->sk_wmem_alloc),
1634 1635 atomic_read(&sp->sk_rmem_alloc),
1635 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  
1639 1640 int udp4_seq_show(struct seq_file *seq, void *v)
1640 1641  
1641 1642  
... ... @@ -1644,11 +1645,11 @@
1644 1645 "rx_queue tr tm->when retrnsmt uid timeout "
1645 1646 "inode");
1646 1647 else {
1647   - char tmpbuf[129];
1648 1648 struct udp_iter_state *state = seq->private;
  1649 + int len;
1649 1650  
1650   - udp4_format_sock(v, tmpbuf, state->bucket);
1651   - seq_printf(seq, "%-127s\n", tmpbuf);
  1651 + udp4_format_sock(v, seq, state->bucket, &len);
  1652 + seq_printf(seq, "%*s\n", 127 - len ,"");
1652 1653 }
1653 1654 return 0;
1654 1655 }
... ... @@ -83,13 +83,12 @@
83 83 */
84 84 static int sctp_objcnt_seq_show(struct seq_file *seq, void *v)
85 85 {
86   - int i;
87   - char temp[128];
  86 + int i, len;
88 87  
89 88 i = (int)*(loff_t *)v;
90   - sprintf(temp, "%s: %d", sctp_dbg_objcnt[i].label,
91   - atomic_read(sctp_dbg_objcnt[i].counter));
92   - seq_printf(seq, "%-127s\n", temp);
  89 + seq_printf(seq, "%s: %d%n", sctp_dbg_objcnt[i].label,
  90 + atomic_read(sctp_dbg_objcnt[i].counter), &len);
  91 + seq_printf(seq, "%*s\n", 127 - len, "");
93 92 return 0;
94 93 }
95 94