OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [tags/] [linux-2.6/] [linux-2.6.24_or32_unified_v2.3/] [net/] [sunrpc/] [stats.c] - Blame information for rev 3

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 * linux/net/sunrpc/stats.c
3
 *
4
 * procfs-based user access to generic RPC statistics. The stats files
5
 * reside in /proc/net/rpc.
6
 *
7
 * The read routines assume that the buffer passed in is just big enough.
8
 * If you implement an RPC service that has its own stats routine which
9
 * appends the generic RPC stats, make sure you don't exceed the PAGE_SIZE
10
 * limit.
11
 *
12
 * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de>
13
 */
14
 
15
#include <linux/module.h>
16
 
17
#include <linux/init.h>
18
#include <linux/kernel.h>
19
#include <linux/proc_fs.h>
20
#include <linux/seq_file.h>
21
#include <linux/sunrpc/clnt.h>
22
#include <linux/sunrpc/svcsock.h>
23
#include <linux/sunrpc/metrics.h>
24
#include <net/net_namespace.h>
25
 
26
#define RPCDBG_FACILITY RPCDBG_MISC
27
 
28
struct proc_dir_entry   *proc_net_rpc = NULL;
29
 
30
/*
31
 * Get RPC client stats
32
 */
33
static int rpc_proc_show(struct seq_file *seq, void *v) {
34
        const struct rpc_stat   *statp = seq->private;
35
        const struct rpc_program *prog = statp->program;
36
        int             i, j;
37
 
38
        seq_printf(seq,
39
                "net %u %u %u %u\n",
40
                        statp->netcnt,
41
                        statp->netudpcnt,
42
                        statp->nettcpcnt,
43
                        statp->nettcpconn);
44
        seq_printf(seq,
45
                "rpc %u %u %u\n",
46
                        statp->rpccnt,
47
                        statp->rpcretrans,
48
                        statp->rpcauthrefresh);
49
 
50
        for (i = 0; i < prog->nrvers; i++) {
51
                const struct rpc_version *vers = prog->version[i];
52
                if (!vers)
53
                        continue;
54
                seq_printf(seq, "proc%u %u",
55
                                        vers->number, vers->nrprocs);
56
                for (j = 0; j < vers->nrprocs; j++)
57
                        seq_printf(seq, " %u",
58
                                        vers->procs[j].p_count);
59
                seq_putc(seq, '\n');
60
        }
61
        return 0;
62
}
63
 
64
static int rpc_proc_open(struct inode *inode, struct file *file)
65
{
66
        return single_open(file, rpc_proc_show, PDE(inode)->data);
67
}
68
 
69
static const struct file_operations rpc_proc_fops = {
70
        .owner = THIS_MODULE,
71
        .open = rpc_proc_open,
72
        .read  = seq_read,
73
        .llseek = seq_lseek,
74
        .release = single_release,
75
};
76
 
77
/*
78
 * Get RPC server stats
79
 */
80
void svc_seq_show(struct seq_file *seq, const struct svc_stat *statp) {
81
        const struct svc_program *prog = statp->program;
82
        const struct svc_procedure *proc;
83
        const struct svc_version *vers;
84
        int             i, j;
85
 
86
        seq_printf(seq,
87
                "net %u %u %u %u\n",
88
                        statp->netcnt,
89
                        statp->netudpcnt,
90
                        statp->nettcpcnt,
91
                        statp->nettcpconn);
92
        seq_printf(seq,
93
                "rpc %u %u %u %u %u\n",
94
                        statp->rpccnt,
95
                        statp->rpcbadfmt+statp->rpcbadauth+statp->rpcbadclnt,
96
                        statp->rpcbadfmt,
97
                        statp->rpcbadauth,
98
                        statp->rpcbadclnt);
99
 
100
        for (i = 0; i < prog->pg_nvers; i++) {
101
                if (!(vers = prog->pg_vers[i]) || !(proc = vers->vs_proc))
102
                        continue;
103
                seq_printf(seq, "proc%d %u", i, vers->vs_nproc);
104
                for (j = 0; j < vers->vs_nproc; j++, proc++)
105
                        seq_printf(seq, " %u", proc->pc_count);
106
                seq_putc(seq, '\n');
107
        }
108
}
109
 
110
/**
111
 * rpc_alloc_iostats - allocate an rpc_iostats structure
112
 * @clnt: RPC program, version, and xprt
113
 *
114
 */
115
struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt)
116
{
117
        struct rpc_iostats *new;
118
        new = kcalloc(clnt->cl_maxproc, sizeof(struct rpc_iostats), GFP_KERNEL);
119
        return new;
120
}
121
EXPORT_SYMBOL(rpc_alloc_iostats);
122
 
123
/**
124
 * rpc_free_iostats - release an rpc_iostats structure
125
 * @stats: doomed rpc_iostats structure
126
 *
127
 */
128
void rpc_free_iostats(struct rpc_iostats *stats)
129
{
130
        kfree(stats);
131
}
132
EXPORT_SYMBOL(rpc_free_iostats);
133
 
134
/**
135
 * rpc_count_iostats - tally up per-task stats
136
 * @task: completed rpc_task
137
 *
138
 * Relies on the caller for serialization.
139
 */
140
void rpc_count_iostats(struct rpc_task *task)
141
{
142
        struct rpc_rqst *req = task->tk_rqstp;
143
        struct rpc_iostats *stats = task->tk_client->cl_metrics;
144
        struct rpc_iostats *op_metrics;
145
        long rtt, execute, queue;
146
 
147
        if (!stats || !req)
148
                return;
149
        op_metrics = &stats[task->tk_msg.rpc_proc->p_statidx];
150
 
151
        op_metrics->om_ops++;
152
        op_metrics->om_ntrans += req->rq_ntrans;
153
        op_metrics->om_timeouts += task->tk_timeouts;
154
 
155
        op_metrics->om_bytes_sent += task->tk_bytes_sent;
156
        op_metrics->om_bytes_recv += req->rq_received;
157
 
158
        queue = (long)req->rq_xtime - task->tk_start;
159
        if (queue < 0)
160
                queue = -queue;
161
        op_metrics->om_queue += queue;
162
 
163
        rtt = task->tk_rtt;
164
        if (rtt < 0)
165
                rtt = -rtt;
166
        op_metrics->om_rtt += rtt;
167
 
168
        execute = (long)jiffies - task->tk_start;
169
        if (execute < 0)
170
                execute = -execute;
171
        op_metrics->om_execute += execute;
172
}
173
 
174
static void _print_name(struct seq_file *seq, unsigned int op,
175
                        struct rpc_procinfo *procs)
176
{
177
        if (procs[op].p_name)
178
                seq_printf(seq, "\t%12s: ", procs[op].p_name);
179
        else if (op == 0)
180
                seq_printf(seq, "\t        NULL: ");
181
        else
182
                seq_printf(seq, "\t%12u: ", op);
183
}
184
 
185
#define MILLISECS_PER_JIFFY     (1000 / HZ)
186
 
187
void rpc_print_iostats(struct seq_file *seq, struct rpc_clnt *clnt)
188
{
189
        struct rpc_iostats *stats = clnt->cl_metrics;
190
        struct rpc_xprt *xprt = clnt->cl_xprt;
191
        unsigned int op, maxproc = clnt->cl_maxproc;
192
 
193
        if (!stats)
194
                return;
195
 
196
        seq_printf(seq, "\tRPC iostats version: %s  ", RPC_IOSTATS_VERS);
197
        seq_printf(seq, "p/v: %u/%u (%s)\n",
198
                        clnt->cl_prog, clnt->cl_vers, clnt->cl_protname);
199
 
200
        if (xprt)
201
                xprt->ops->print_stats(xprt, seq);
202
 
203
        seq_printf(seq, "\tper-op statistics\n");
204
        for (op = 0; op < maxproc; op++) {
205
                struct rpc_iostats *metrics = &stats[op];
206
                _print_name(seq, op, clnt->cl_procinfo);
207
                seq_printf(seq, "%lu %lu %lu %Lu %Lu %Lu %Lu %Lu\n",
208
                                metrics->om_ops,
209
                                metrics->om_ntrans,
210
                                metrics->om_timeouts,
211
                                metrics->om_bytes_sent,
212
                                metrics->om_bytes_recv,
213
                                metrics->om_queue * MILLISECS_PER_JIFFY,
214
                                metrics->om_rtt * MILLISECS_PER_JIFFY,
215
                                metrics->om_execute * MILLISECS_PER_JIFFY);
216
        }
217
}
218
EXPORT_SYMBOL(rpc_print_iostats);
219
 
220
/*
221
 * Register/unregister RPC proc files
222
 */
223
static inline struct proc_dir_entry *
224
do_register(const char *name, void *data, const struct file_operations *fops)
225
{
226
        struct proc_dir_entry *ent;
227
 
228
        rpc_proc_init();
229
        dprintk("RPC:       registering /proc/net/rpc/%s\n", name);
230
 
231
        ent = create_proc_entry(name, 0, proc_net_rpc);
232
        if (ent) {
233
                ent->proc_fops = fops;
234
                ent->data = data;
235
        }
236
        return ent;
237
}
238
 
239
struct proc_dir_entry *
240
rpc_proc_register(struct rpc_stat *statp)
241
{
242
        return do_register(statp->program->name, statp, &rpc_proc_fops);
243
}
244
 
245
void
246
rpc_proc_unregister(const char *name)
247
{
248
        remove_proc_entry(name, proc_net_rpc);
249
}
250
 
251
struct proc_dir_entry *
252
svc_proc_register(struct svc_stat *statp, const struct file_operations *fops)
253
{
254
        return do_register(statp->program->pg_name, statp, fops);
255
}
256
 
257
void
258
svc_proc_unregister(const char *name)
259
{
260
        remove_proc_entry(name, proc_net_rpc);
261
}
262
 
263
void
264
rpc_proc_init(void)
265
{
266
        dprintk("RPC:       registering /proc/net/rpc\n");
267
        if (!proc_net_rpc) {
268
                struct proc_dir_entry *ent;
269
                ent = proc_mkdir("rpc", init_net.proc_net);
270
                if (ent) {
271
                        ent->owner = THIS_MODULE;
272
                        proc_net_rpc = ent;
273
                }
274
        }
275
}
276
 
277
void
278
rpc_proc_exit(void)
279
{
280
        dprintk("RPC:       unregistering /proc/net/rpc\n");
281
        if (proc_net_rpc) {
282
                proc_net_rpc = NULL;
283
                remove_proc_entry("rpc", init_net.proc_net);
284
        }
285
}
286
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.