diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-03-01 17:00:56 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-03-02 15:36:38 -0500 |
commit | 2446ab6070861aba2dd9229463ffbc40016a9f33 (patch) | |
tree | 2e366c3236788936b9f4f58c0787ae01c265f4a4 /net/sunrpc/stats.c | |
parent | a3ca5651cb5eebe2e56e510bbf5cd60abc301c9f (diff) |
SUNRPC: Use RCU to dereference the rpc_clnt.cl_xprt field
A migration event will replace the rpc_xprt used by an rpc_clnt. To
ensure this can be done safely, all references to cl_xprt must now use
a form of rcu_dereference().
Special care is taken with rpc_peeraddr2str(), which returns a pointer
to memory whose lifetime is the same as the rpc_xprt.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
[ cel: fix lockdep splats and layering violations ]
[ cel: forward ported to 3.4 ]
[ cel: remove rpc_max_reqs(), add rpc_net_ns() ]
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc/stats.c')
-rw-r--r-- | net/sunrpc/stats.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c index 1eb3304bc105..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 | ||
@@ -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++) { |