Commit 0a702195 authored by Weston Andros Adamson's avatar Weston Andros Adamson Committed by Trond Myklebust

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: default avatarWeston Andros Adamson <dros@netapp.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent b6bf6e7d
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
#include <linux/nfs_page.h> #include <linux/nfs_page.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/sunrpc/metrics.h>
#include "internal.h" #include "internal.h"
#include "nfs4filelayout.h" #include "nfs4filelayout.h"
...@@ -189,6 +191,13 @@ static void filelayout_read_call_done(struct rpc_task *task, void *data) ...@@ -189,6 +191,13 @@ static void filelayout_read_call_done(struct rpc_task *task, void *data)
rdata->mds_ops->rpc_call_done(task, data); rdata->mds_ops->rpc_call_done(task, data);
} }
static void filelayout_read_count_stats(struct rpc_task *task, void *data)
{
struct nfs_read_data *rdata = (struct nfs_read_data *)data;
rpc_count_iostats(task, NFS_SERVER(rdata->inode)->client->cl_metrics);
}
static void filelayout_read_release(void *data) static void filelayout_read_release(void *data)
{ {
struct nfs_read_data *rdata = (struct nfs_read_data *)data; struct nfs_read_data *rdata = (struct nfs_read_data *)data;
...@@ -268,6 +277,13 @@ static void filelayout_write_call_done(struct rpc_task *task, void *data) ...@@ -268,6 +277,13 @@ static void filelayout_write_call_done(struct rpc_task *task, void *data)
wdata->mds_ops->rpc_call_done(task, data); wdata->mds_ops->rpc_call_done(task, data);
} }
static void filelayout_write_count_stats(struct rpc_task *task, void *data)
{
struct nfs_write_data *wdata = (struct nfs_write_data *)data;
rpc_count_iostats(task, NFS_SERVER(wdata->inode)->client->cl_metrics);
}
static void filelayout_write_release(void *data) static void filelayout_write_release(void *data)
{ {
struct nfs_write_data *wdata = (struct nfs_write_data *)data; struct nfs_write_data *wdata = (struct nfs_write_data *)data;
...@@ -288,18 +304,21 @@ static void filelayout_commit_release(void *data) ...@@ -288,18 +304,21 @@ static void filelayout_commit_release(void *data)
struct rpc_call_ops filelayout_read_call_ops = { struct rpc_call_ops filelayout_read_call_ops = {
.rpc_call_prepare = filelayout_read_prepare, .rpc_call_prepare = filelayout_read_prepare,
.rpc_call_done = filelayout_read_call_done, .rpc_call_done = filelayout_read_call_done,
.rpc_count_stats = filelayout_read_count_stats,
.rpc_release = filelayout_read_release, .rpc_release = filelayout_read_release,
}; };
struct rpc_call_ops filelayout_write_call_ops = { struct rpc_call_ops filelayout_write_call_ops = {
.rpc_call_prepare = filelayout_write_prepare, .rpc_call_prepare = filelayout_write_prepare,
.rpc_call_done = filelayout_write_call_done, .rpc_call_done = filelayout_write_call_done,
.rpc_count_stats = filelayout_write_count_stats,
.rpc_release = filelayout_write_release, .rpc_release = filelayout_write_release,
}; };
struct rpc_call_ops filelayout_commit_call_ops = { struct rpc_call_ops filelayout_commit_call_ops = {
.rpc_call_prepare = filelayout_write_prepare, .rpc_call_prepare = filelayout_write_prepare,
.rpc_call_done = filelayout_write_call_done, .rpc_call_done = filelayout_write_call_done,
.rpc_count_stats = filelayout_write_count_stats,
.rpc_release = filelayout_commit_release, .rpc_release = filelayout_commit_release,
}; };
......
...@@ -74,14 +74,16 @@ struct rpc_clnt; ...@@ -74,14 +74,16 @@ struct rpc_clnt;
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
struct rpc_iostats * rpc_alloc_iostats(struct rpc_clnt *); struct rpc_iostats * rpc_alloc_iostats(struct rpc_clnt *);
void rpc_count_iostats(struct rpc_task *); void rpc_count_iostats(const struct rpc_task *,
struct rpc_iostats *);
void rpc_print_iostats(struct seq_file *, struct rpc_clnt *); void rpc_print_iostats(struct seq_file *, struct rpc_clnt *);
void rpc_free_iostats(struct rpc_iostats *); void rpc_free_iostats(struct rpc_iostats *);
#else /* CONFIG_PROC_FS */ #else /* CONFIG_PROC_FS */
static inline struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt) { return NULL; } static inline struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt) { return NULL; }
static inline void rpc_count_iostats(struct rpc_task *task) {} static inline void rpc_count_iostats(const struct rpc_task *task,
struct rpc_iostats *stats) {}
static inline void rpc_print_iostats(struct seq_file *seq, struct rpc_clnt *clnt) {} static inline void rpc_print_iostats(struct seq_file *seq, struct rpc_clnt *clnt) {}
static inline void rpc_free_iostats(struct rpc_iostats *stats) {} static inline void rpc_free_iostats(struct rpc_iostats *stats) {}
......
...@@ -103,6 +103,7 @@ typedef void (*rpc_action)(struct rpc_task *); ...@@ -103,6 +103,7 @@ typedef void (*rpc_action)(struct rpc_task *);
struct rpc_call_ops { struct rpc_call_ops {
void (*rpc_call_prepare)(struct rpc_task *, void *); void (*rpc_call_prepare)(struct rpc_task *, void *);
void (*rpc_call_done)(struct rpc_task *, void *); void (*rpc_call_done)(struct rpc_task *, void *);
void (*rpc_count_stats)(struct rpc_task *, void *);
void (*rpc_release)(void *); void (*rpc_release)(void *);
}; };
......
...@@ -133,20 +133,19 @@ EXPORT_SYMBOL_GPL(rpc_free_iostats); ...@@ -133,20 +133,19 @@ EXPORT_SYMBOL_GPL(rpc_free_iostats);
/** /**
* rpc_count_iostats - tally up per-task stats * rpc_count_iostats - tally up per-task stats
* @task: completed rpc_task * @task: completed rpc_task
* @stats: array of stat structures
* *
* Relies on the caller for serialization. * Relies on the caller for serialization.
*/ */
void rpc_count_iostats(struct rpc_task *task) void rpc_count_iostats(const struct rpc_task *task, struct rpc_iostats *stats)
{ {
struct rpc_rqst *req = task->tk_rqstp; struct rpc_rqst *req = task->tk_rqstp;
struct rpc_iostats *stats;
struct rpc_iostats *op_metrics; struct rpc_iostats *op_metrics;
ktime_t delta; ktime_t delta;
if (!task->tk_client || !task->tk_client->cl_metrics || !req) if (!stats || !req)
return; return;
stats = task->tk_client->cl_metrics;
op_metrics = &stats[task->tk_msg.rpc_proc->p_statidx]; op_metrics = &stats[task->tk_msg.rpc_proc->p_statidx];
op_metrics->om_ops++; op_metrics->om_ops++;
...@@ -164,6 +163,7 @@ void rpc_count_iostats(struct rpc_task *task) ...@@ -164,6 +163,7 @@ void rpc_count_iostats(struct rpc_task *task)
delta = ktime_sub(ktime_get(), task->tk_start); delta = ktime_sub(ktime_get(), task->tk_start);
op_metrics->om_execute = ktime_add(op_metrics->om_execute, delta); op_metrics->om_execute = ktime_add(op_metrics->om_execute, delta);
} }
EXPORT_SYMBOL_GPL(rpc_count_iostats);
static void _print_name(struct seq_file *seq, unsigned int op, static void _print_name(struct seq_file *seq, unsigned int op,
struct rpc_procinfo *procs) struct rpc_procinfo *procs)
......
...@@ -1137,7 +1137,10 @@ void xprt_release(struct rpc_task *task) ...@@ -1137,7 +1137,10 @@ void xprt_release(struct rpc_task *task)
return; return;
xprt = req->rq_xprt; xprt = req->rq_xprt;
rpc_count_iostats(task); if (task->tk_ops->rpc_count_stats != NULL)
task->tk_ops->rpc_count_stats(task, task->tk_calldata);
else if (task->tk_client)
rpc_count_iostats(task, task->tk_client->cl_metrics);
spin_lock_bh(&xprt->transport_lock); spin_lock_bh(&xprt->transport_lock);
xprt->ops->release_xprt(xprt, task); xprt->ops->release_xprt(xprt, task);
if (xprt->ops->release_request) if (xprt->ops->release_request)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment