aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorGerrit Renker <gerrit@erg.abdn.ac.uk>2008-09-04 01:30:19 -0400
committerGerrit Renker <gerrit@erg.abdn.ac.uk>2008-09-04 01:45:36 -0400
commitb8c6bcee1dbc1aadcd67af998e414e73fa166a7d (patch)
treeac391375ffdbb5c3617fcb8672b83c6eff72bbe6 /net
parenta9c1656ab10480cc6f6d34f193bcde2729fe8037 (diff)
dccp: Reduce noise in output and convert to ktime_t
This fixes the problem that dccp_probe output can grow quite large without apparent benefit (many identical data points), creating huge files (up to over one Gigabyte for a few minutes' test run) which are very hard to post-process (in one instance it got so bad that gnuplot ate up all memory plus swap). The cause for the problem is that the kprobe is inserted into dccp_sendmsg(), which can be called in a polling-mode (whenever the TX queue is full due to congestion-control issues, EAGAIN is returned). This creates many very similar data points, i.e. the increase of processing time does not increase the quality/information of the probe output. The fix is to attach the probe to a different function -- write_xmit was chosen since it gets called continually (both via userspace and timer); an input-path function would stop sampling as soon as the other end stops sending feedback. For comparison the output file sizes for the same 20 second test run over a lossy link: * before / without patch: 118 Megabytes * after / with patch: 1.2 Megabytes and there was much less noise in the output. To allow backward compatibility with scripts that people use, the now-unused `size' field in the output has been replaced with the CCID identifier. This also serves for future compatibility - support for CCID2 is work in progress (depends on the still unfinished SRTT/RTTVAR updates). While at it, the update to ktime_t was also performed. Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk> Acked-by: Ian McDonald <ian.mcdonald@jandi.co.nz>
Diffstat (limited to 'net')
-rw-r--r--net/dccp/probe.c66
1 files changed, 25 insertions, 41 deletions
diff --git a/net/dccp/probe.c b/net/dccp/probe.c
index a87fd4fc1b3d..eaa59d82ab0f 100644
--- a/net/dccp/probe.c
+++ b/net/dccp/probe.c
@@ -46,70 +46,54 @@ static struct {
46 struct kfifo *fifo; 46 struct kfifo *fifo;
47 spinlock_t lock; 47 spinlock_t lock;
48 wait_queue_head_t wait; 48 wait_queue_head_t wait;
49 struct timespec tstart; 49 ktime_t start;
50} dccpw; 50} dccpw;
51 51
52static void printl(const char *fmt, ...) 52static void jdccp_write_xmit(struct sock *sk)
53{
54 va_list args;
55 int len;
56 struct timespec now;
57 char tbuf[256];
58
59 va_start(args, fmt);
60 getnstimeofday(&now);
61
62 now = timespec_sub(now, dccpw.tstart);
63
64 len = sprintf(tbuf, "%lu.%06lu ",
65 (unsigned long) now.tv_sec,
66 (unsigned long) now.tv_nsec / NSEC_PER_USEC);
67 len += vscnprintf(tbuf+len, sizeof(tbuf)-len, fmt, args);
68 va_end(args);
69
70 kfifo_put(dccpw.fifo, tbuf, len);
71 wake_up(&dccpw.wait);
72}
73
74static int jdccp_sendmsg(struct kiocb *iocb, struct sock *sk,
75 struct msghdr *msg, size_t size)
76{ 53{
77 const struct inet_sock *inet = inet_sk(sk); 54 const struct inet_sock *inet = inet_sk(sk);
78 struct ccid3_hc_tx_sock *hctx = NULL; 55 struct ccid3_hc_tx_sock *hctx = NULL;
56 struct timespec tv;
57 char buf[256];
58 int len, ccid = ccid_get_current_tx_ccid(dccp_sk(sk));
79 59
80 if (ccid_get_current_tx_ccid(dccp_sk(sk)) == DCCPC_CCID3) 60 if (ccid == DCCPC_CCID3)
81 hctx = ccid3_hc_tx_sk(sk); 61 hctx = ccid3_hc_tx_sk(sk);
82 62
83 if (port == 0 || ntohs(inet->dport) == port || 63 if (!port || ntohs(inet->dport) == port || ntohs(inet->sport) == port) {
84 ntohs(inet->sport) == port) { 64
85 if (hctx) 65 tv = ktime_to_timespec(ktime_sub(ktime_get(), dccpw.start));
86 printl("%d.%d.%d.%d:%u %d.%d.%d.%d:%u %d %d %d %d %u " 66 len = sprintf(buf, "%lu.%09lu %d.%d.%d.%d:%u %d.%d.%d.%d:%u %d",
87 "%llu %llu %d\n", 67 (unsigned long)tv.tv_sec,
68 (unsigned long)tv.tv_nsec,
88 NIPQUAD(inet->saddr), ntohs(inet->sport), 69 NIPQUAD(inet->saddr), ntohs(inet->sport),
89 NIPQUAD(inet->daddr), ntohs(inet->dport), size, 70 NIPQUAD(inet->daddr), ntohs(inet->dport), ccid);
71
72 if (hctx)
73 len += sprintf(buf + len, " %d %d %d %u %u %u %d",
90 hctx->s, hctx->rtt, hctx->p, hctx->x_calc, 74 hctx->s, hctx->rtt, hctx->p, hctx->x_calc,
91 hctx->x_recv >> 6, hctx->x >> 6, hctx->t_ipi); 75 (unsigned)(hctx->x_recv >> 6),
92 else 76 (unsigned)(hctx->x >> 6), hctx->t_ipi);
93 printl("%d.%d.%d.%d:%u %d.%d.%d.%d:%u %d\n", 77
94 NIPQUAD(inet->saddr), ntohs(inet->sport), 78 len += sprintf(buf + len, "\n");
95 NIPQUAD(inet->daddr), ntohs(inet->dport), size); 79 kfifo_put(dccpw.fifo, buf, len);
80 wake_up(&dccpw.wait);
96 } 81 }
97 82
98 jprobe_return(); 83 jprobe_return();
99 return 0;
100} 84}
101 85
102static struct jprobe dccp_send_probe = { 86static struct jprobe dccp_send_probe = {
103 .kp = { 87 .kp = {
104 .symbol_name = "dccp_sendmsg", 88 .symbol_name = "dccp_write_xmit",
105 }, 89 },
106 .entry = jdccp_sendmsg, 90 .entry = jdccp_write_xmit,
107}; 91};
108 92
109static int dccpprobe_open(struct inode *inode, struct file *file) 93static int dccpprobe_open(struct inode *inode, struct file *file)
110{ 94{
111 kfifo_reset(dccpw.fifo); 95 kfifo_reset(dccpw.fifo);
112 getnstimeofday(&dccpw.tstart); 96 dccpw.start = ktime_get();
113 return 0; 97 return 0;
114} 98}
115 99