Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

NFS: include filelayout DS rpc stats in mountstats

Include RPC statistics from all data servers in /proc/self/mountstats for pNFS
filelayout mounts.

Signed-off-by: Weston Andros Adamson <dros@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>

authored by

Weston Andros Adamson and committed by
Trond Myklebust
0a702195 b6bf6e7d

+32 -7
+19
fs/nfs/nfs4filelayout.c
··· 33 33 #include <linux/nfs_page.h> 34 34 #include <linux/module.h> 35 35 36 + #include <linux/sunrpc/metrics.h> 37 + 36 38 #include "internal.h" 37 39 #include "nfs4filelayout.h" 38 40 ··· 191 189 rdata->mds_ops->rpc_call_done(task, data); 192 190 } 193 191 192 + static void filelayout_read_count_stats(struct rpc_task *task, void *data) 193 + { 194 + struct nfs_read_data *rdata = (struct nfs_read_data *)data; 195 + 196 + rpc_count_iostats(task, NFS_SERVER(rdata->inode)->client->cl_metrics); 197 + } 198 + 194 199 static void filelayout_read_release(void *data) 195 200 { 196 201 struct nfs_read_data *rdata = (struct nfs_read_data *)data; ··· 277 268 wdata->mds_ops->rpc_call_done(task, data); 278 269 } 279 270 271 + static void filelayout_write_count_stats(struct rpc_task *task, void *data) 272 + { 273 + struct nfs_write_data *wdata = (struct nfs_write_data *)data; 274 + 275 + rpc_count_iostats(task, NFS_SERVER(wdata->inode)->client->cl_metrics); 276 + } 277 + 280 278 static void filelayout_write_release(void *data) 281 279 { 282 280 struct nfs_write_data *wdata = (struct nfs_write_data *)data; ··· 304 288 struct rpc_call_ops filelayout_read_call_ops = { 305 289 .rpc_call_prepare = filelayout_read_prepare, 306 290 .rpc_call_done = filelayout_read_call_done, 291 + .rpc_count_stats = filelayout_read_count_stats, 307 292 .rpc_release = filelayout_read_release, 308 293 }; 309 294 310 295 struct rpc_call_ops filelayout_write_call_ops = { 311 296 .rpc_call_prepare = filelayout_write_prepare, 312 297 .rpc_call_done = filelayout_write_call_done, 298 + .rpc_count_stats = filelayout_write_count_stats, 313 299 .rpc_release = filelayout_write_release, 314 300 }; 315 301 316 302 struct rpc_call_ops filelayout_commit_call_ops = { 317 303 .rpc_call_prepare = filelayout_write_prepare, 318 304 .rpc_call_done = filelayout_write_call_done, 305 + .rpc_count_stats = filelayout_write_count_stats, 319 306 .rpc_release = filelayout_commit_release, 320 307 }; 321 308
+4 -2
include/linux/sunrpc/metrics.h
··· 74 74 #ifdef CONFIG_PROC_FS 75 75 76 76 struct rpc_iostats * rpc_alloc_iostats(struct rpc_clnt *); 77 - void rpc_count_iostats(struct rpc_task *); 77 + void rpc_count_iostats(const struct rpc_task *, 78 + struct rpc_iostats *); 78 79 void rpc_print_iostats(struct seq_file *, struct rpc_clnt *); 79 80 void rpc_free_iostats(struct rpc_iostats *); 80 81 81 82 #else /* CONFIG_PROC_FS */ 82 83 83 84 static inline struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt) { return NULL; } 84 - static inline void rpc_count_iostats(struct rpc_task *task) {} 85 + static inline void rpc_count_iostats(const struct rpc_task *task, 86 + struct rpc_iostats *stats) {} 85 87 static inline void rpc_print_iostats(struct seq_file *seq, struct rpc_clnt *clnt) {} 86 88 static inline void rpc_free_iostats(struct rpc_iostats *stats) {} 87 89
+1
include/linux/sunrpc/sched.h
··· 103 103 struct rpc_call_ops { 104 104 void (*rpc_call_prepare)(struct rpc_task *, void *); 105 105 void (*rpc_call_done)(struct rpc_task *, void *); 106 + void (*rpc_count_stats)(struct rpc_task *, void *); 106 107 void (*rpc_release)(void *); 107 108 }; 108 109
+4 -4
net/sunrpc/stats.c
··· 133 133 /** 134 134 * rpc_count_iostats - tally up per-task stats 135 135 * @task: completed rpc_task 136 + * @stats: array of stat structures 136 137 * 137 138 * Relies on the caller for serialization. 138 139 */ 139 - void rpc_count_iostats(struct rpc_task *task) 140 + void rpc_count_iostats(const struct rpc_task *task, struct rpc_iostats *stats) 140 141 { 141 142 struct rpc_rqst *req = task->tk_rqstp; 142 - struct rpc_iostats *stats; 143 143 struct rpc_iostats *op_metrics; 144 144 ktime_t delta; 145 145 146 - if (!task->tk_client || !task->tk_client->cl_metrics || !req) 146 + if (!stats || !req) 147 147 return; 148 148 149 - stats = task->tk_client->cl_metrics; 150 149 op_metrics = &stats[task->tk_msg.rpc_proc->p_statidx]; 151 150 152 151 op_metrics->om_ops++; ··· 163 164 delta = ktime_sub(ktime_get(), task->tk_start); 164 165 op_metrics->om_execute = ktime_add(op_metrics->om_execute, delta); 165 166 } 167 + EXPORT_SYMBOL_GPL(rpc_count_iostats); 166 168 167 169 static void _print_name(struct seq_file *seq, unsigned int op, 168 170 struct rpc_procinfo *procs)
+4 -1
net/sunrpc/xprt.c
··· 1137 1137 return; 1138 1138 1139 1139 xprt = req->rq_xprt; 1140 - rpc_count_iostats(task); 1140 + if (task->tk_ops->rpc_count_stats != NULL) 1141 + task->tk_ops->rpc_count_stats(task, task->tk_calldata); 1142 + else if (task->tk_client) 1143 + rpc_count_iostats(task, task->tk_client->cl_metrics); 1141 1144 spin_lock_bh(&xprt->transport_lock); 1142 1145 xprt->ops->release_xprt(xprt, task); 1143 1146 if (xprt->ops->release_request)