[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>
This commit is contained in:
parent
3d36696024
commit
5e659e4cb0
|
@ -1003,7 +1003,7 @@ static unsigned fib_flag_trans(int type, __be32 mask, struct fib_info *fi)
|
||||||
static int fib_seq_show(struct seq_file *seq, void *v)
|
static int fib_seq_show(struct seq_file *seq, void *v)
|
||||||
{
|
{
|
||||||
struct fib_iter_state *iter;
|
struct fib_iter_state *iter;
|
||||||
char bf[128];
|
int len;
|
||||||
__be32 prefix, mask;
|
__be32 prefix, mask;
|
||||||
unsigned flags;
|
unsigned flags;
|
||||||
struct fib_node *f;
|
struct fib_node *f;
|
||||||
|
@ -1025,18 +1025,19 @@ static int fib_seq_show(struct seq_file *seq, void *v)
|
||||||
mask = FZ_MASK(iter->zone);
|
mask = FZ_MASK(iter->zone);
|
||||||
flags = fib_flag_trans(fa->fa_type, mask, fi);
|
flags = fib_flag_trans(fa->fa_type, mask, fi);
|
||||||
if (fi)
|
if (fi)
|
||||||
snprintf(bf, sizeof(bf),
|
seq_printf(seq,
|
||||||
"%s\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u",
|
"%s\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u%n",
|
||||||
fi->fib_dev ? fi->fib_dev->name : "*", prefix,
|
fi->fib_dev ? fi->fib_dev->name : "*", prefix,
|
||||||
fi->fib_nh->nh_gw, flags, 0, 0, fi->fib_priority,
|
fi->fib_nh->nh_gw, flags, 0, 0, fi->fib_priority,
|
||||||
mask, (fi->fib_advmss ? fi->fib_advmss + 40 : 0),
|
mask, (fi->fib_advmss ? fi->fib_advmss + 40 : 0),
|
||||||
fi->fib_window,
|
fi->fib_window,
|
||||||
fi->fib_rtt >> 3);
|
fi->fib_rtt >> 3, &len);
|
||||||
else
|
else
|
||||||
snprintf(bf, sizeof(bf),
|
seq_printf(seq,
|
||||||
"*\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u",
|
"*\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u%n",
|
||||||
prefix, 0, flags, 0, 0, 0, mask, 0, 0, 0);
|
prefix, 0, flags, 0, 0, 0, mask, 0, 0, 0, &len);
|
||||||
seq_printf(seq, "%-127s\n", bf);
|
|
||||||
|
seq_printf(seq, "%*s\n", 127 - len, "");
|
||||||
out:
|
out:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2602,15 +2602,16 @@ static int fib_route_seq_show(struct seq_file *seq, void *v)
|
||||||
list_for_each_entry_rcu(fa, &li->falh, fa_list) {
|
list_for_each_entry_rcu(fa, &li->falh, fa_list) {
|
||||||
const struct fib_info *fi = fa->fa_info;
|
const struct fib_info *fi = fa->fa_info;
|
||||||
unsigned flags = fib_flag_trans(fa->fa_type, mask, fi);
|
unsigned flags = fib_flag_trans(fa->fa_type, mask, fi);
|
||||||
char bf[128];
|
int len;
|
||||||
|
|
||||||
if (fa->fa_type == RTN_BROADCAST
|
if (fa->fa_type == RTN_BROADCAST
|
||||||
|| fa->fa_type == RTN_MULTICAST)
|
|| fa->fa_type == RTN_MULTICAST)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (fi)
|
if (fi)
|
||||||
snprintf(bf, sizeof(bf),
|
seq_printf(seq,
|
||||||
"%s\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u",
|
"%s\t%08X\t%08X\t%04X\t%d\t%u\t"
|
||||||
|
"%d\t%08X\t%d\t%u\t%u%n",
|
||||||
fi->fib_dev ? fi->fib_dev->name : "*",
|
fi->fib_dev ? fi->fib_dev->name : "*",
|
||||||
prefix,
|
prefix,
|
||||||
fi->fib_nh->nh_gw, flags, 0, 0,
|
fi->fib_nh->nh_gw, flags, 0, 0,
|
||||||
|
@ -2619,14 +2620,15 @@ static int fib_route_seq_show(struct seq_file *seq, void *v)
|
||||||
(fi->fib_advmss ?
|
(fi->fib_advmss ?
|
||||||
fi->fib_advmss + 40 : 0),
|
fi->fib_advmss + 40 : 0),
|
||||||
fi->fib_window,
|
fi->fib_window,
|
||||||
fi->fib_rtt >> 3);
|
fi->fib_rtt >> 3, &len);
|
||||||
else
|
else
|
||||||
snprintf(bf, sizeof(bf),
|
seq_printf(seq,
|
||||||
"*\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u",
|
"*\t%08X\t%08X\t%04X\t%d\t%u\t"
|
||||||
|
"%d\t%08X\t%d\t%u\t%u%n",
|
||||||
prefix, 0, flags, 0, 0, 0,
|
prefix, 0, flags, 0, 0, 0,
|
||||||
mask, 0, 0, 0);
|
mask, 0, 0, 0, &len);
|
||||||
|
|
||||||
seq_printf(seq, "%-127s\n", bf);
|
seq_printf(seq, "%*s\n", 127 - len, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -367,10 +367,10 @@ static int rt_cache_seq_show(struct seq_file *seq, void *v)
|
||||||
"HHUptod\tSpecDst");
|
"HHUptod\tSpecDst");
|
||||||
else {
|
else {
|
||||||
struct rtable *r = v;
|
struct rtable *r = v;
|
||||||
char temp[256];
|
int len;
|
||||||
|
|
||||||
sprintf(temp, "%s\t%08lX\t%08lX\t%8X\t%d\t%u\t%d\t"
|
seq_printf(seq, "%s\t%08lX\t%08lX\t%8X\t%d\t%u\t%d\t"
|
||||||
"%08lX\t%d\t%u\t%u\t%02X\t%d\t%1d\t%08X",
|
"%08lX\t%d\t%u\t%u\t%02X\t%d\t%1d\t%08X%n",
|
||||||
r->u.dst.dev ? r->u.dst.dev->name : "*",
|
r->u.dst.dev ? r->u.dst.dev->name : "*",
|
||||||
(unsigned long)r->rt_dst, (unsigned long)r->rt_gateway,
|
(unsigned long)r->rt_dst, (unsigned long)r->rt_gateway,
|
||||||
r->rt_flags, atomic_read(&r->u.dst.__refcnt),
|
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)
|
||||||
r->u.dst.hh ? atomic_read(&r->u.dst.hh->hh_refcnt) : -1,
|
r->u.dst.hh ? atomic_read(&r->u.dst.hh->hh_refcnt) : -1,
|
||||||
r->u.dst.hh ? (r->u.dst.hh->hh_output ==
|
r->u.dst.hh ? (r->u.dst.hh->hh_output ==
|
||||||
dev_queue_xmit) : 0,
|
dev_queue_xmit) : 0,
|
||||||
r->rt_spec_dst);
|
r->rt_spec_dst, &len);
|
||||||
seq_printf(seq, "%-127s\n", temp);
|
|
||||||
|
seq_printf(seq, "%*s\n", 127 - len, "");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
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);
|
const struct inet_request_sock *ireq = inet_rsk(req);
|
||||||
int ttd = req->expires - jiffies;
|
int ttd = req->expires - jiffies;
|
||||||
|
|
||||||
sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
|
seq_printf(f, "%4d: %08X:%04X %08X:%04X"
|
||||||
" %02X %08X:%08X %02X:%08lX %08X %5d %8d %u %d %p",
|
" %02X %08X:%08X %02X:%08lX %08X %5d %8d %u %d %p%n",
|
||||||
i,
|
i,
|
||||||
ireq->loc_addr,
|
ireq->loc_addr,
|
||||||
ntohs(inet_sk(sk)->sport),
|
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, /* non standard timer */
|
||||||
0, /* open_requests have no inode */
|
0, /* open_requests have no inode */
|
||||||
atomic_read(&sk->sk_refcnt),
|
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;
|
int timer_active;
|
||||||
unsigned long timer_expires;
|
unsigned long timer_expires;
|
||||||
|
@ -2305,8 +2306,8 @@ static void get_tcp4_sock(struct sock *sk, char *tmpbuf, int i)
|
||||||
timer_expires = jiffies;
|
timer_expires = jiffies;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX "
|
seq_printf(f, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX "
|
||||||
"%08X %5d %8d %lu %d %p %u %u %u %u %d",
|
"%08X %5d %8d %lu %d %p %u %u %u %u %d%n",
|
||||||
i, src, srcp, dest, destp, sk->sk_state,
|
i, src, srcp, dest, destp, sk->sk_state,
|
||||||
tp->write_seq - tp->snd_una,
|
tp->write_seq - tp->snd_una,
|
||||||
sk->sk_state == TCP_LISTEN ? sk->sk_ack_backlog :
|
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.ato,
|
||||||
(icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong,
|
(icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong,
|
||||||
tp->snd_cwnd,
|
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,
|
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;
|
__be32 dest, src;
|
||||||
__u16 destp, srcp;
|
__u16 destp, srcp;
|
||||||
|
@ -2340,11 +2342,11 @@ static void get_timewait4_sock(struct inet_timewait_sock *tw,
|
||||||
destp = ntohs(tw->tw_dport);
|
destp = ntohs(tw->tw_dport);
|
||||||
srcp = ntohs(tw->tw_sport);
|
srcp = ntohs(tw->tw_sport);
|
||||||
|
|
||||||
sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
|
seq_printf(f, "%4d: %08X:%04X %08X:%04X"
|
||||||
" %02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %p",
|
" %02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %p%n",
|
||||||
i, src, srcp, dest, destp, tw->tw_substate, 0, 0,
|
i, src, srcp, dest, destp, tw->tw_substate, 0, 0,
|
||||||
3, jiffies_to_clock_t(ttd), 0, 0, 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
|
#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)
|
static int tcp4_seq_show(struct seq_file *seq, void *v)
|
||||||
{
|
{
|
||||||
struct tcp_iter_state* st;
|
struct tcp_iter_state* st;
|
||||||
char tmpbuf[TMPSZ + 1];
|
int len;
|
||||||
|
|
||||||
if (v == SEQ_START_TOKEN) {
|
if (v == SEQ_START_TOKEN) {
|
||||||
seq_printf(seq, "%-*s\n", TMPSZ - 1,
|
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) {
|
switch (st->state) {
|
||||||
case TCP_SEQ_STATE_LISTENING:
|
case TCP_SEQ_STATE_LISTENING:
|
||||||
case TCP_SEQ_STATE_ESTABLISHED:
|
case TCP_SEQ_STATE_ESTABLISHED:
|
||||||
get_tcp4_sock(v, tmpbuf, st->num);
|
get_tcp4_sock(v, seq, st->num, &len);
|
||||||
break;
|
break;
|
||||||
case TCP_SEQ_STATE_OPENREQ:
|
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;
|
break;
|
||||||
case TCP_SEQ_STATE_TIME_WAIT:
|
case TCP_SEQ_STATE_TIME_WAIT:
|
||||||
get_timewait4_sock(v, tmpbuf, st->num);
|
get_timewait4_sock(v, seq, st->num, &len);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
seq_printf(seq, "%-*s\n", TMPSZ - 1, tmpbuf);
|
seq_printf(seq, "%*s\n", TMPSZ - 1 - len, "");
|
||||||
out:
|
out:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1619,7 +1619,8 @@ void udp_proc_unregister(struct net *net, struct udp_seq_afinfo *afinfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
static void udp4_format_sock(struct sock *sp, char *tmpbuf, int bucket)
|
static void udp4_format_sock(struct sock *sp, struct seq_file *f,
|
||||||
|
int bucket, int *len)
|
||||||
{
|
{
|
||||||
struct inet_sock *inet = inet_sk(sp);
|
struct inet_sock *inet = inet_sk(sp);
|
||||||
__be32 dest = inet->daddr;
|
__be32 dest = inet->daddr;
|
||||||
|
@ -1627,13 +1628,13 @@ static void udp4_format_sock(struct sock *sp, char *tmpbuf, int bucket)
|
||||||
__u16 destp = ntohs(inet->dport);
|
__u16 destp = ntohs(inet->dport);
|
||||||
__u16 srcp = ntohs(inet->sport);
|
__u16 srcp = ntohs(inet->sport);
|
||||||
|
|
||||||
sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
|
seq_printf(f, "%4d: %08X:%04X %08X:%04X"
|
||||||
" %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p",
|
" %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p%n",
|
||||||
bucket, src, srcp, dest, destp, sp->sk_state,
|
bucket, src, srcp, dest, destp, sp->sk_state,
|
||||||
atomic_read(&sp->sk_wmem_alloc),
|
atomic_read(&sp->sk_wmem_alloc),
|
||||||
atomic_read(&sp->sk_rmem_alloc),
|
atomic_read(&sp->sk_rmem_alloc),
|
||||||
0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp),
|
0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp),
|
||||||
atomic_read(&sp->sk_refcnt), sp);
|
atomic_read(&sp->sk_refcnt), sp, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
int udp4_seq_show(struct seq_file *seq, void *v)
|
int udp4_seq_show(struct seq_file *seq, void *v)
|
||||||
|
@ -1644,11 +1645,11 @@ int udp4_seq_show(struct seq_file *seq, void *v)
|
||||||
"rx_queue tr tm->when retrnsmt uid timeout "
|
"rx_queue tr tm->when retrnsmt uid timeout "
|
||||||
"inode");
|
"inode");
|
||||||
else {
|
else {
|
||||||
char tmpbuf[129];
|
|
||||||
struct udp_iter_state *state = seq->private;
|
struct udp_iter_state *state = seq->private;
|
||||||
|
int len;
|
||||||
|
|
||||||
udp4_format_sock(v, tmpbuf, state->bucket);
|
udp4_format_sock(v, seq, state->bucket, &len);
|
||||||
seq_printf(seq, "%-127s\n", tmpbuf);
|
seq_printf(seq, "%*s\n", 127 - len ,"");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,13 +83,12 @@ static sctp_dbg_objcnt_entry_t sctp_dbg_objcnt[] = {
|
||||||
*/
|
*/
|
||||||
static int sctp_objcnt_seq_show(struct seq_file *seq, void *v)
|
static int sctp_objcnt_seq_show(struct seq_file *seq, void *v)
|
||||||
{
|
{
|
||||||
int i;
|
int i, len;
|
||||||
char temp[128];
|
|
||||||
|
|
||||||
i = (int)*(loff_t *)v;
|
i = (int)*(loff_t *)v;
|
||||||
sprintf(temp, "%s: %d", sctp_dbg_objcnt[i].label,
|
seq_printf(seq, "%s: %d%n", sctp_dbg_objcnt[i].label,
|
||||||
atomic_read(sctp_dbg_objcnt[i].counter));
|
atomic_read(sctp_dbg_objcnt[i].counter), &len);
|
||||||
seq_printf(seq, "%-127s\n", temp);
|
seq_printf(seq, "%*s\n", 127 - len, "");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue