aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/stats.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-03-25 12:18:27 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-25 12:18:27 -0500
commit53846a21c1766326bb14ce8ab6e997a0c120675d (patch)
tree37b04485e29844b4e734479181276a2f4d2447e4 /net/sunrpc/stats.c
parent2e9abdd9bad485970b37cd53a82f92702054984c (diff)
parent1ebbe2b20091d306453a5cf480a87e6cd28ae76f (diff)
Merge git://git.linux-nfs.org/pub/linux/nfs-2.6
* git://git.linux-nfs.org/pub/linux/nfs-2.6: (103 commits) SUNRPC,RPCSEC_GSS: spkm3--fix config dependencies SUNRPC,RPCSEC_GSS: spkm3: import contexts using NID_cast5_cbc LOCKD: Make nlmsvc_traverse_shares return void LOCKD: nlmsvc_traverse_blocks return is unused SUNRPC,RPCSEC_GSS: fix krb5 sequence numbers. NFSv4: Dont list system.nfs4_acl for filesystems that don't support it. SUNRPC,RPCSEC_GSS: remove unnecessary kmalloc of a checksum SUNRPC: Ensure rpc_call_async() always calls tk_ops->rpc_release() SUNRPC: Fix memory barriers for req->rq_received NFS: Fix a race in nfs_sync_inode() NFS: Clean up nfs_flush_list() NFS: Fix a race with PG_private and nfs_release_page() NFSv4: Ensure the callback daemon flushes signals SUNRPC: Fix a 'Busy inodes' error in rpc_pipefs NFS, NLM: Allow blocking locks to respect signals NFS: Make nfs_fhget() return appropriate error values NFSv4: Fix an oops in nfs4_fill_super lockd: blocks should hold a reference to the nlm_file NFSv4: SETCLIENTID_CONFIRM should handle NFS4ERR_DELAY/NFS4ERR_RESOURCE NFSv4: Send the delegation stateid for SETATTR calls ...
Diffstat (limited to 'net/sunrpc/stats.c')
-rw-r--r--net/sunrpc/stats.c115
1 files changed, 115 insertions, 0 deletions
diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c
index 4979f226e285..790941e8af4d 100644
--- a/net/sunrpc/stats.c
+++ b/net/sunrpc/stats.c
@@ -21,6 +21,7 @@
21#include <linux/seq_file.h> 21#include <linux/seq_file.h>
22#include <linux/sunrpc/clnt.h> 22#include <linux/sunrpc/clnt.h>
23#include <linux/sunrpc/svcsock.h> 23#include <linux/sunrpc/svcsock.h>
24#include <linux/sunrpc/metrics.h>
24 25
25#define RPCDBG_FACILITY RPCDBG_MISC 26#define RPCDBG_FACILITY RPCDBG_MISC
26 27
@@ -106,6 +107,120 @@ void svc_seq_show(struct seq_file *seq, const struct svc_stat *statp) {
106 } 107 }
107} 108}
108 109
110/**
111 * rpc_alloc_iostats - allocate an rpc_iostats structure
112 * @clnt: RPC program, version, and xprt
113 *
114 */
115struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt)
116{
117 unsigned int ops = clnt->cl_maxproc;
118 size_t size = ops * sizeof(struct rpc_iostats);
119 struct rpc_iostats *new;
120
121 new = kmalloc(size, GFP_KERNEL);
122 if (new)
123 memset(new, 0 , size);
124 return new;
125}
126EXPORT_SYMBOL(rpc_alloc_iostats);
127
128/**
129 * rpc_free_iostats - release an rpc_iostats structure
130 * @stats: doomed rpc_iostats structure
131 *
132 */
133void rpc_free_iostats(struct rpc_iostats *stats)
134{
135 kfree(stats);
136}
137EXPORT_SYMBOL(rpc_free_iostats);
138
139/**
140 * rpc_count_iostats - tally up per-task stats
141 * @task: completed rpc_task
142 *
143 * Relies on the caller for serialization.
144 */
145void rpc_count_iostats(struct rpc_task *task)
146{
147 struct rpc_rqst *req = task->tk_rqstp;
148 struct rpc_iostats *stats = task->tk_client->cl_metrics;
149 struct rpc_iostats *op_metrics;
150 long rtt, execute, queue;
151
152 if (!stats || !req)
153 return;
154 op_metrics = &stats[task->tk_msg.rpc_proc->p_statidx];
155
156 op_metrics->om_ops++;
157 op_metrics->om_ntrans += req->rq_ntrans;
158 op_metrics->om_timeouts += task->tk_timeouts;
159
160 op_metrics->om_bytes_sent += task->tk_bytes_sent;
161 op_metrics->om_bytes_recv += req->rq_received;
162
163 queue = (long)req->rq_xtime - task->tk_start;
164 if (queue < 0)
165 queue = -queue;
166 op_metrics->om_queue += queue;
167
168 rtt = task->tk_rtt;
169 if (rtt < 0)
170 rtt = -rtt;
171 op_metrics->om_rtt += rtt;
172
173 execute = (long)jiffies - task->tk_start;
174 if (execute < 0)
175 execute = -execute;
176 op_metrics->om_execute += execute;
177}
178
179void _print_name(struct seq_file *seq, unsigned int op, struct rpc_procinfo *procs)
180{
181 if (procs[op].p_name)
182 seq_printf(seq, "\t%12s: ", procs[op].p_name);
183 else if (op == 0)
184 seq_printf(seq, "\t NULL: ");
185 else
186 seq_printf(seq, "\t%12u: ", op);
187}
188
189#define MILLISECS_PER_JIFFY (1000 / HZ)
190
191void rpc_print_iostats(struct seq_file *seq, struct rpc_clnt *clnt)
192{
193 struct rpc_iostats *stats = clnt->cl_metrics;
194 struct rpc_xprt *xprt = clnt->cl_xprt;
195 unsigned int op, maxproc = clnt->cl_maxproc;
196
197 if (!stats)
198 return;
199
200 seq_printf(seq, "\tRPC iostats version: %s ", RPC_IOSTATS_VERS);
201 seq_printf(seq, "p/v: %u/%u (%s)\n",
202 clnt->cl_prog, clnt->cl_vers, clnt->cl_protname);
203
204 if (xprt)
205 xprt->ops->print_stats(xprt, seq);
206
207 seq_printf(seq, "\tper-op statistics\n");
208 for (op = 0; op < maxproc; op++) {
209 struct rpc_iostats *metrics = &stats[op];
210 _print_name(seq, op, clnt->cl_procinfo);
211 seq_printf(seq, "%lu %lu %lu %Lu %Lu %Lu %Lu %Lu\n",
212 metrics->om_ops,
213 metrics->om_ntrans,
214 metrics->om_timeouts,
215 metrics->om_bytes_sent,
216 metrics->om_bytes_recv,
217 metrics->om_queue * MILLISECS_PER_JIFFY,
218 metrics->om_rtt * MILLISECS_PER_JIFFY,
219 metrics->om_execute * MILLISECS_PER_JIFFY);
220 }
221}
222EXPORT_SYMBOL(rpc_print_iostats);
223
109/* 224/*
110 * Register/unregister RPC proc files 225 * Register/unregister RPC proc files
111 */ 226 */