diff options
Diffstat (limited to 'net/sunrpc/stats.c')
-rw-r--r-- | net/sunrpc/stats.c | 35 |
1 files changed, 20 insertions, 15 deletions
diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c index 80df89d957ba..bc2068ee795b 100644 --- a/net/sunrpc/stats.c +++ b/net/sunrpc/stats.c | |||
@@ -22,6 +22,7 @@ | |||
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 | #include <linux/sunrpc/metrics.h> |
25 | #include <linux/rcupdate.h> | ||
25 | 26 | ||
26 | #include "netns.h" | 27 | #include "netns.h" |
27 | 28 | ||
@@ -133,20 +134,19 @@ EXPORT_SYMBOL_GPL(rpc_free_iostats); | |||
133 | /** | 134 | /** |
134 | * rpc_count_iostats - tally up per-task stats | 135 | * rpc_count_iostats - tally up per-task stats |
135 | * @task: completed rpc_task | 136 | * @task: completed rpc_task |
137 | * @stats: array of stat structures | ||
136 | * | 138 | * |
137 | * Relies on the caller for serialization. | 139 | * Relies on the caller for serialization. |
138 | */ | 140 | */ |
139 | void rpc_count_iostats(struct rpc_task *task) | 141 | void rpc_count_iostats(const struct rpc_task *task, struct rpc_iostats *stats) |
140 | { | 142 | { |
141 | struct rpc_rqst *req = task->tk_rqstp; | 143 | struct rpc_rqst *req = task->tk_rqstp; |
142 | struct rpc_iostats *stats; | ||
143 | struct rpc_iostats *op_metrics; | 144 | struct rpc_iostats *op_metrics; |
144 | ktime_t delta; | 145 | ktime_t delta; |
145 | 146 | ||
146 | if (!task->tk_client || !task->tk_client->cl_metrics || !req) | 147 | if (!stats || !req) |
147 | return; | 148 | return; |
148 | 149 | ||
149 | stats = task->tk_client->cl_metrics; | ||
150 | op_metrics = &stats[task->tk_msg.rpc_proc->p_statidx]; | 150 | op_metrics = &stats[task->tk_msg.rpc_proc->p_statidx]; |
151 | 151 | ||
152 | op_metrics->om_ops++; | 152 | op_metrics->om_ops++; |
@@ -164,6 +164,7 @@ void rpc_count_iostats(struct rpc_task *task) | |||
164 | delta = ktime_sub(ktime_get(), task->tk_start); | 164 | delta = ktime_sub(ktime_get(), task->tk_start); |
165 | op_metrics->om_execute = ktime_add(op_metrics->om_execute, delta); | 165 | op_metrics->om_execute = ktime_add(op_metrics->om_execute, delta); |
166 | } | 166 | } |
167 | EXPORT_SYMBOL_GPL(rpc_count_iostats); | ||
167 | 168 | ||
168 | static void _print_name(struct seq_file *seq, unsigned int op, | 169 | static void _print_name(struct seq_file *seq, unsigned int op, |
169 | struct rpc_procinfo *procs) | 170 | struct rpc_procinfo *procs) |
@@ -179,7 +180,7 @@ static void _print_name(struct seq_file *seq, unsigned int op, | |||
179 | void rpc_print_iostats(struct seq_file *seq, struct rpc_clnt *clnt) | 180 | void rpc_print_iostats(struct seq_file *seq, struct rpc_clnt *clnt) |
180 | { | 181 | { |
181 | struct rpc_iostats *stats = clnt->cl_metrics; | 182 | struct rpc_iostats *stats = clnt->cl_metrics; |
182 | struct rpc_xprt *xprt = clnt->cl_xprt; | 183 | struct rpc_xprt *xprt; |
183 | unsigned int op, maxproc = clnt->cl_maxproc; | 184 | unsigned int op, maxproc = clnt->cl_maxproc; |
184 | 185 | ||
185 | if (!stats) | 186 | if (!stats) |
@@ -189,8 +190,11 @@ void rpc_print_iostats(struct seq_file *seq, struct rpc_clnt *clnt) | |||
189 | seq_printf(seq, "p/v: %u/%u (%s)\n", | 190 | seq_printf(seq, "p/v: %u/%u (%s)\n", |
190 | clnt->cl_prog, clnt->cl_vers, clnt->cl_protname); | 191 | clnt->cl_prog, clnt->cl_vers, clnt->cl_protname); |
191 | 192 | ||
193 | rcu_read_lock(); | ||
194 | xprt = rcu_dereference(clnt->cl_xprt); | ||
192 | if (xprt) | 195 | if (xprt) |
193 | xprt->ops->print_stats(xprt, seq); | 196 | xprt->ops->print_stats(xprt, seq); |
197 | rcu_read_unlock(); | ||
194 | 198 | ||
195 | seq_printf(seq, "\tper-op statistics\n"); | 199 | seq_printf(seq, "\tper-op statistics\n"); |
196 | for (op = 0; op < maxproc; op++) { | 200 | for (op = 0; op < maxproc; op++) { |
@@ -213,45 +217,46 @@ EXPORT_SYMBOL_GPL(rpc_print_iostats); | |||
213 | * Register/unregister RPC proc files | 217 | * Register/unregister RPC proc files |
214 | */ | 218 | */ |
215 | static inline struct proc_dir_entry * | 219 | static inline struct proc_dir_entry * |
216 | do_register(const char *name, void *data, const struct file_operations *fops) | 220 | do_register(struct net *net, const char *name, void *data, |
221 | const struct file_operations *fops) | ||
217 | { | 222 | { |
218 | struct sunrpc_net *sn; | 223 | struct sunrpc_net *sn; |
219 | 224 | ||
220 | dprintk("RPC: registering /proc/net/rpc/%s\n", name); | 225 | dprintk("RPC: registering /proc/net/rpc/%s\n", name); |
221 | sn = net_generic(&init_net, sunrpc_net_id); | 226 | sn = net_generic(net, sunrpc_net_id); |
222 | return proc_create_data(name, 0, sn->proc_net_rpc, fops, data); | 227 | return proc_create_data(name, 0, sn->proc_net_rpc, fops, data); |
223 | } | 228 | } |
224 | 229 | ||
225 | struct proc_dir_entry * | 230 | struct proc_dir_entry * |
226 | rpc_proc_register(struct rpc_stat *statp) | 231 | rpc_proc_register(struct net *net, struct rpc_stat *statp) |
227 | { | 232 | { |
228 | return do_register(statp->program->name, statp, &rpc_proc_fops); | 233 | return do_register(net, statp->program->name, statp, &rpc_proc_fops); |
229 | } | 234 | } |
230 | EXPORT_SYMBOL_GPL(rpc_proc_register); | 235 | EXPORT_SYMBOL_GPL(rpc_proc_register); |
231 | 236 | ||
232 | void | 237 | void |
233 | rpc_proc_unregister(const char *name) | 238 | rpc_proc_unregister(struct net *net, const char *name) |
234 | { | 239 | { |
235 | struct sunrpc_net *sn; | 240 | struct sunrpc_net *sn; |
236 | 241 | ||
237 | sn = net_generic(&init_net, sunrpc_net_id); | 242 | sn = net_generic(net, sunrpc_net_id); |
238 | remove_proc_entry(name, sn->proc_net_rpc); | 243 | remove_proc_entry(name, sn->proc_net_rpc); |
239 | } | 244 | } |
240 | EXPORT_SYMBOL_GPL(rpc_proc_unregister); | 245 | EXPORT_SYMBOL_GPL(rpc_proc_unregister); |
241 | 246 | ||
242 | struct proc_dir_entry * | 247 | struct proc_dir_entry * |
243 | svc_proc_register(struct svc_stat *statp, const struct file_operations *fops) | 248 | svc_proc_register(struct net *net, struct svc_stat *statp, const struct file_operations *fops) |
244 | { | 249 | { |
245 | return do_register(statp->program->pg_name, statp, fops); | 250 | return do_register(net, statp->program->pg_name, statp, fops); |
246 | } | 251 | } |
247 | EXPORT_SYMBOL_GPL(svc_proc_register); | 252 | EXPORT_SYMBOL_GPL(svc_proc_register); |
248 | 253 | ||
249 | void | 254 | void |
250 | svc_proc_unregister(const char *name) | 255 | svc_proc_unregister(struct net *net, const char *name) |
251 | { | 256 | { |
252 | struct sunrpc_net *sn; | 257 | struct sunrpc_net *sn; |
253 | 258 | ||
254 | sn = net_generic(&init_net, sunrpc_net_id); | 259 | sn = net_generic(net, sunrpc_net_id); |
255 | remove_proc_entry(name, sn->proc_net_rpc); | 260 | remove_proc_entry(name, sn->proc_net_rpc); |
256 | } | 261 | } |
257 | EXPORT_SYMBOL_GPL(svc_proc_unregister); | 262 | EXPORT_SYMBOL_GPL(svc_proc_unregister); |