summaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_ipv4.c
diff options
context:
space:
mode:
authorPavel Emelyanov2008-04-24 10:02:16 +0200
committerDavid S. Miller2008-04-24 10:02:16 +0200
commit5e659e4cb0eedacdc1f621a61e400a4611ddef8a (patch)
treefa3c8743010dd640c48584a6fa8a910d27350c01 /net/ipv4/tcp_ipv4.c
parent[AF_UNIX] Initialise UNIX sockets before general device initcalls (diff)
downloadkernel-qcow2-linux-5e659e4cb0eedacdc1f621a61e400a4611ddef8a.tar.gz
kernel-qcow2-linux-5e659e4cb0eedacdc1f621a61e400a4611ddef8a.tar.xz
kernel-qcow2-linux-5e659e4cb0eedacdc1f621a61e400a4611ddef8a.zip
[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/tcp_ipv4.c')
-rw-r--r--net/ipv4/tcp_ipv4.c36
1 files changed, 19 insertions, 17 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 776615180b93..0e9bc120707d 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)
}
static void get_openreq4(struct sock *sk, struct request_sock *req,
- char *tmpbuf, int i, int uid)
+ struct seq_file *f, int i, int uid, int *len)
{
const struct inet_request_sock *ireq = inet_rsk(req);
int ttd = req->expires - jiffies;
- sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
- " %02X %08X:%08X %02X:%08lX %08X %5d %8d %u %d %p",
+ seq_printf(f, "%4d: %08X:%04X %08X:%04X"
+ " %02X %08X:%08X %02X:%08lX %08X %5d %8d %u %d %p%n",
i,
ireq->loc_addr,
ntohs(inet_sk(sk)->sport),
@@ -2276,10 +2276,11 @@ static void get_openreq4(struct sock *sk, struct request_sock *req,
0, /* non standard timer */
0, /* open_requests have no inode */
atomic_read(&sk->sk_refcnt),
- req);
+ req,
+ len);
}
-static void get_tcp4_sock(struct sock *sk, char *tmpbuf, int i)
+static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len)
{
int timer_active;
unsigned long timer_expires;
@@ -2305,8 +2306,8 @@ static void get_tcp4_sock(struct sock *sk, char *tmpbuf, int i)
timer_expires = jiffies;
}
- sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX "
- "%08X %5d %8d %lu %d %p %u %u %u %u %d",
+ seq_printf(f, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX "
+ "%08X %5d %8d %lu %d %p %u %u %u %u %d%n",
i, src, srcp, dest, destp, sk->sk_state,
tp->write_seq - tp->snd_una,
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)
icsk->icsk_ack.ato,
(icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong,
tp->snd_cwnd,
- tp->snd_ssthresh >= 0xFFFF ? -1 : tp->snd_ssthresh);
+ tp->snd_ssthresh >= 0xFFFF ? -1 : tp->snd_ssthresh,
+ len);
}
static void get_timewait4_sock(struct inet_timewait_sock *tw,
- char *tmpbuf, int i)
+ struct seq_file *f, int i, int *len)
{
__be32 dest, src;
__u16 destp, srcp;
@@ -2340,11 +2342,11 @@ static void get_timewait4_sock(struct inet_timewait_sock *tw,
destp = ntohs(tw->tw_dport);
srcp = ntohs(tw->tw_sport);
- sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
- " %02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %p",
+ seq_printf(f, "%4d: %08X:%04X %08X:%04X"
+ " %02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %p%n",
i, src, srcp, dest, destp, tw->tw_substate, 0, 0,
3, jiffies_to_clock_t(ttd), 0, 0, 0, 0,
- atomic_read(&tw->tw_refcnt), tw);
+ atomic_read(&tw->tw_refcnt), tw, len);
}
#define TMPSZ 150
@@ -2352,7 +2354,7 @@ static void get_timewait4_sock(struct inet_timewait_sock *tw,
static int tcp4_seq_show(struct seq_file *seq, void *v)
{
struct tcp_iter_state* st;
- char tmpbuf[TMPSZ + 1];
+ int len;
if (v == SEQ_START_TOKEN) {
seq_printf(seq, "%-*s\n", TMPSZ - 1,
@@ -2366,16 +2368,16 @@ static int tcp4_seq_show(struct seq_file *seq, void *v)
switch (st->state) {
case TCP_SEQ_STATE_LISTENING:
case TCP_SEQ_STATE_ESTABLISHED:
- get_tcp4_sock(v, tmpbuf, st->num);
+ get_tcp4_sock(v, seq, st->num, &len);
break;
case TCP_SEQ_STATE_OPENREQ:
- get_openreq4(st->syn_wait_sk, v, tmpbuf, st->num, st->uid);
+ get_openreq4(st->syn_wait_sk, v, seq, st->num, st->uid, &len);
break;
case TCP_SEQ_STATE_TIME_WAIT:
- get_timewait4_sock(v, tmpbuf, st->num);
+ get_timewait4_sock(v, seq, st->num, &len);
break;
}
- seq_printf(seq, "%-*s\n", TMPSZ - 1, tmpbuf);
+ seq_printf(seq, "%*s\n", TMPSZ - 1 - len, "");
out:
return 0;
}