Skip to content

Commit 7f5667a

Browse files
chuckleveramschuma-ntap
authored andcommitted
SUNRPC: Clean up rpc_verify_header()
- Recover some instruction count because I'm about to introduce a few xdr_inline_decode call sites - Replace dprintk() call sites with trace points - Reduce the hot path so it fits in fewer cachelines I've also renamed it rpc_decode_header() to match everything else in the RPC client. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
1 parent e8680a2 commit 7f5667a

File tree

3 files changed

+154
-128
lines changed

3 files changed

+154
-128
lines changed

include/linux/sunrpc/xdr.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ xdr_buf_init(struct xdr_buf *buf, void *start, size_t len)
9292
#define rpc_auth_gss cpu_to_be32(RPC_AUTH_GSS)
9393

9494
#define rpc_call cpu_to_be32(RPC_CALL)
95+
#define rpc_reply cpu_to_be32(RPC_REPLY)
96+
97+
#define rpc_msg_accepted cpu_to_be32(RPC_MSG_ACCEPTED)
9598

9699
#define rpc_success cpu_to_be32(RPC_SUCCESS)
97100
#define rpc_prog_unavail cpu_to_be32(RPC_PROG_UNAVAIL)
@@ -101,6 +104,9 @@ xdr_buf_init(struct xdr_buf *buf, void *start, size_t len)
101104
#define rpc_system_err cpu_to_be32(RPC_SYSTEM_ERR)
102105
#define rpc_drop_reply cpu_to_be32(RPC_DROP_REPLY)
103106

107+
#define rpc_mismatch cpu_to_be32(RPC_MISMATCH)
108+
#define rpc_auth_error cpu_to_be32(RPC_AUTH_ERROR)
109+
104110
#define rpc_auth_ok cpu_to_be32(RPC_AUTH_OK)
105111
#define rpc_autherr_badcred cpu_to_be32(RPC_AUTH_BADCRED)
106112
#define rpc_autherr_rejectedcred cpu_to_be32(RPC_AUTH_REJECTEDCRED)
@@ -109,7 +115,6 @@ xdr_buf_init(struct xdr_buf *buf, void *start, size_t len)
109115
#define rpc_autherr_tooweak cpu_to_be32(RPC_AUTH_TOOWEAK)
110116
#define rpcsec_gsserr_credproblem cpu_to_be32(RPCSEC_GSS_CREDPROBLEM)
111117
#define rpcsec_gsserr_ctxproblem cpu_to_be32(RPCSEC_GSS_CTXPROBLEM)
112-
#define rpc_autherr_oldseqnum cpu_to_be32(101)
113118

114119
/*
115120
* Miscellaneous XDR helper functions

include/trace/events/sunrpc.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,58 @@ DECLARE_EVENT_CLASS(rpc_failure,
241241
TP_ARGS(task))
242242

243243
DEFINE_RPC_FAILURE(callhdr);
244+
DEFINE_RPC_FAILURE(verifier);
245+
246+
DECLARE_EVENT_CLASS(rpc_reply_event,
247+
248+
TP_PROTO(
249+
const struct rpc_task *task
250+
),
251+
252+
TP_ARGS(task),
253+
254+
TP_STRUCT__entry(
255+
__field(unsigned int, task_id)
256+
__field(unsigned int, client_id)
257+
__field(u32, xid)
258+
__string(progname, task->tk_client->cl_program->name)
259+
__field(u32, version)
260+
__string(procname, rpc_proc_name(task))
261+
__string(servername, task->tk_xprt->servername)
262+
),
263+
264+
TP_fast_assign(
265+
__entry->task_id = task->tk_pid;
266+
__entry->client_id = task->tk_client->cl_clid;
267+
__entry->xid = be32_to_cpu(task->tk_rqstp->rq_xid);
268+
__assign_str(progname, task->tk_client->cl_program->name)
269+
__entry->version = task->tk_client->cl_vers;
270+
__assign_str(procname, rpc_proc_name(task))
271+
__assign_str(servername, task->tk_xprt->servername)
272+
),
273+
274+
TP_printk("task:%u@%d server=%s xid=0x%08x %sv%d %s",
275+
__entry->task_id, __entry->client_id, __get_str(servername),
276+
__entry->xid, __get_str(progname), __entry->version,
277+
__get_str(procname))
278+
)
279+
280+
#define DEFINE_RPC_REPLY_EVENT(name) \
281+
DEFINE_EVENT(rpc_reply_event, rpc__##name, \
282+
TP_PROTO( \
283+
const struct rpc_task *task \
284+
), \
285+
TP_ARGS(task))
286+
287+
DEFINE_RPC_REPLY_EVENT(prog_unavail);
288+
DEFINE_RPC_REPLY_EVENT(prog_mismatch);
289+
DEFINE_RPC_REPLY_EVENT(proc_unavail);
290+
DEFINE_RPC_REPLY_EVENT(garbage_args);
291+
DEFINE_RPC_REPLY_EVENT(unparsable);
292+
DEFINE_RPC_REPLY_EVENT(mismatch);
293+
DEFINE_RPC_REPLY_EVENT(stale_creds);
294+
DEFINE_RPC_REPLY_EVENT(bad_creds);
295+
DEFINE_RPC_REPLY_EVENT(auth_tooweak);
244296

245297
TRACE_EVENT(rpc_stats_latency,
246298

net/sunrpc/clnt.c

Lines changed: 96 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ static void call_connect_status(struct rpc_task *task);
7979

8080
static int rpc_encode_header(struct rpc_task *task,
8181
struct xdr_stream *xdr);
82-
static __be32 *rpc_verify_header(struct rpc_task *task);
82+
static __be32 *rpc_decode_header(struct rpc_task *task);
8383
static int rpc_ping(struct rpc_clnt *clnt);
8484

8585
static void rpc_register_client(struct rpc_clnt *clnt)
@@ -2292,7 +2292,7 @@ call_decode(struct rpc_task *task)
22922292
goto out_retry;
22932293
}
22942294

2295-
p = rpc_verify_header(task);
2295+
p = rpc_decode_header(task);
22962296
if (IS_ERR(p)) {
22972297
if (p == ERR_PTR(-EAGAIN))
22982298
goto out_retry;
@@ -2308,7 +2308,7 @@ call_decode(struct rpc_task *task)
23082308
return;
23092309
out_retry:
23102310
task->tk_status = 0;
2311-
/* Note: rpc_verify_header() may have freed the RPC slot */
2311+
/* Note: rpc_decode_header() may have freed the RPC slot */
23122312
if (task->tk_rqstp == req) {
23132313
xdr_free_bvec(&req->rq_rcv_buf);
23142314
req->rq_reply_bytes_recvd = req->rq_rcv_buf.len = 0;
@@ -2347,164 +2347,133 @@ rpc_encode_header(struct rpc_task *task, struct xdr_stream *xdr)
23472347
return error;
23482348
}
23492349

2350-
static __be32 *
2351-
rpc_verify_header(struct rpc_task *task)
2350+
static noinline __be32 *
2351+
rpc_decode_header(struct rpc_task *task)
23522352
{
23532353
struct rpc_clnt *clnt = task->tk_client;
23542354
struct kvec *iov = &task->tk_rqstp->rq_rcv_buf.head[0];
23552355
int len = task->tk_rqstp->rq_rcv_buf.len >> 2;
23562356
__be32 *p = iov->iov_base;
2357-
u32 n;
23582357
int error = -EACCES;
23592358

2360-
if ((task->tk_rqstp->rq_rcv_buf.len & 3) != 0) {
2361-
/* RFC-1014 says that the representation of XDR data must be a
2362-
* multiple of four bytes
2363-
* - if it isn't pointer subtraction in the NFS client may give
2364-
* undefined results
2365-
*/
2366-
dprintk("RPC: %5u %s: XDR representation not a multiple of"
2367-
" 4 bytes: 0x%x\n", task->tk_pid, __func__,
2368-
task->tk_rqstp->rq_rcv_buf.len);
2369-
error = -EIO;
2370-
goto out_err;
2371-
}
2359+
/* RFC-1014 says that the representation of XDR data must be a
2360+
* multiple of four bytes
2361+
* - if it isn't pointer subtraction in the NFS client may give
2362+
* undefined results
2363+
*/
2364+
if (task->tk_rqstp->rq_rcv_buf.len & 3)
2365+
goto out_badlen;
23722366
if ((len -= 3) < 0)
2373-
goto out_overflow;
2367+
goto out_unparsable;
23742368

2375-
p += 1; /* skip XID */
2376-
if ((n = ntohl(*p++)) != RPC_REPLY) {
2377-
dprintk("RPC: %5u %s: not an RPC reply: %x\n",
2378-
task->tk_pid, __func__, n);
2379-
error = -EIO;
2380-
goto out_garbage;
2381-
}
2369+
p++; /* skip XID */
2370+
if (*p++ != rpc_reply)
2371+
goto out_unparsable;
2372+
if (*p++ != rpc_msg_accepted)
2373+
goto out_msg_denied;
23822374

2383-
if ((n = ntohl(*p++)) != RPC_MSG_ACCEPTED) {
2384-
if (--len < 0)
2385-
goto out_overflow;
2386-
switch ((n = ntohl(*p++))) {
2387-
case RPC_AUTH_ERROR:
2388-
break;
2389-
case RPC_MISMATCH:
2390-
dprintk("RPC: %5u %s: RPC call version mismatch!\n",
2391-
task->tk_pid, __func__);
2392-
error = -EPROTONOSUPPORT;
2393-
goto out_err;
2394-
default:
2395-
dprintk("RPC: %5u %s: RPC call rejected, "
2396-
"unknown error: %x\n",
2397-
task->tk_pid, __func__, n);
2398-
error = -EIO;
2399-
goto out_err;
2400-
}
2401-
if (--len < 0)
2402-
goto out_overflow;
2403-
switch ((n = ntohl(*p++))) {
2404-
case RPC_AUTH_REJECTEDCRED:
2405-
case RPC_AUTH_REJECTEDVERF:
2406-
case RPCSEC_GSS_CREDPROBLEM:
2407-
case RPCSEC_GSS_CTXPROBLEM:
2408-
if (!task->tk_cred_retry)
2409-
break;
2410-
task->tk_cred_retry--;
2411-
dprintk("RPC: %5u %s: retry stale creds\n",
2412-
task->tk_pid, __func__);
2413-
rpcauth_invalcred(task);
2414-
/* Ensure we obtain a new XID! */
2415-
xprt_release(task);
2416-
task->tk_action = call_reserve;
2417-
goto out_retry;
2418-
case RPC_AUTH_BADCRED:
2419-
case RPC_AUTH_BADVERF:
2420-
/* possibly garbled cred/verf? */
2421-
if (!task->tk_garb_retry)
2422-
break;
2423-
task->tk_garb_retry--;
2424-
dprintk("RPC: %5u %s: retry garbled creds\n",
2425-
task->tk_pid, __func__);
2426-
task->tk_action = call_encode;
2427-
goto out_retry;
2428-
case RPC_AUTH_TOOWEAK:
2429-
printk(KERN_NOTICE "RPC: server %s requires stronger "
2430-
"authentication.\n",
2431-
task->tk_xprt->servername);
2432-
break;
2433-
default:
2434-
dprintk("RPC: %5u %s: unknown auth error: %x\n",
2435-
task->tk_pid, __func__, n);
2436-
error = -EIO;
2437-
}
2438-
dprintk("RPC: %5u %s: call rejected %d\n",
2439-
task->tk_pid, __func__, n);
2440-
goto out_err;
2441-
}
24422375
p = rpcauth_checkverf(task, p);
2443-
if (IS_ERR(p)) {
2444-
error = PTR_ERR(p);
2445-
dprintk("RPC: %5u %s: auth check failed with %d\n",
2446-
task->tk_pid, __func__, error);
2447-
goto out_garbage; /* bad verifier, retry */
2448-
}
2376+
if (IS_ERR(p))
2377+
goto out_verifier;
2378+
24492379
len = p - (__be32 *)iov->iov_base - 1;
24502380
if (len < 0)
2451-
goto out_overflow;
2452-
switch ((n = ntohl(*p++))) {
2453-
case RPC_SUCCESS:
2381+
goto out_unparsable;
2382+
switch (*p++) {
2383+
case rpc_success:
24542384
return p;
2455-
case RPC_PROG_UNAVAIL:
2456-
dprintk("RPC: %5u %s: program %u is unsupported "
2457-
"by server %s\n", task->tk_pid, __func__,
2458-
(unsigned int)clnt->cl_prog,
2459-
task->tk_xprt->servername);
2385+
case rpc_prog_unavail:
2386+
trace_rpc__prog_unavail(task);
24602387
error = -EPFNOSUPPORT;
24612388
goto out_err;
2462-
case RPC_PROG_MISMATCH:
2463-
dprintk("RPC: %5u %s: program %u, version %u unsupported "
2464-
"by server %s\n", task->tk_pid, __func__,
2465-
(unsigned int)clnt->cl_prog,
2466-
(unsigned int)clnt->cl_vers,
2467-
task->tk_xprt->servername);
2389+
case rpc_prog_mismatch:
2390+
trace_rpc__prog_mismatch(task);
24682391
error = -EPROTONOSUPPORT;
24692392
goto out_err;
2470-
case RPC_PROC_UNAVAIL:
2471-
dprintk("RPC: %5u %s: proc %s unsupported by program %u, "
2472-
"version %u on server %s\n",
2473-
task->tk_pid, __func__,
2474-
rpc_proc_name(task),
2475-
clnt->cl_prog, clnt->cl_vers,
2476-
task->tk_xprt->servername);
2393+
case rpc_proc_unavail:
2394+
trace_rpc__proc_unavail(task);
24772395
error = -EOPNOTSUPP;
24782396
goto out_err;
2479-
case RPC_GARBAGE_ARGS:
2480-
dprintk("RPC: %5u %s: server saw garbage\n",
2481-
task->tk_pid, __func__);
2482-
break; /* retry */
2397+
case rpc_garbage_args:
2398+
trace_rpc__garbage_args(task);
2399+
break;
24832400
default:
2484-
dprintk("RPC: %5u %s: server accept status: %x\n",
2485-
task->tk_pid, __func__, n);
2486-
/* Also retry */
2401+
trace_rpc__unparsable(task);
24872402
}
24882403

24892404
out_garbage:
24902405
clnt->cl_stats->rpcgarbage++;
24912406
if (task->tk_garb_retry) {
24922407
task->tk_garb_retry--;
2493-
dprintk("RPC: %5u %s: retrying\n",
2494-
task->tk_pid, __func__);
24952408
task->tk_action = call_encode;
2496-
out_retry:
24972409
return ERR_PTR(-EAGAIN);
24982410
}
24992411
out_err:
25002412
rpc_exit(task, error);
2501-
dprintk("RPC: %5u %s: call failed with error %d\n", task->tk_pid,
2502-
__func__, error);
25032413
return ERR_PTR(error);
2504-
out_overflow:
2505-
dprintk("RPC: %5u %s: server reply was truncated.\n", task->tk_pid,
2506-
__func__);
2414+
2415+
out_badlen:
2416+
trace_rpc__unparsable(task);
2417+
error = -EIO;
2418+
goto out_err;
2419+
2420+
out_unparsable:
2421+
trace_rpc__unparsable(task);
2422+
error = -EIO;
25072423
goto out_garbage;
2424+
2425+
out_verifier:
2426+
trace_rpc_bad_verifier(task);
2427+
error = PTR_ERR(p);
2428+
goto out_garbage;
2429+
2430+
out_msg_denied:
2431+
switch (*p++) {
2432+
case rpc_auth_error:
2433+
break;
2434+
case rpc_mismatch:
2435+
trace_rpc__mismatch(task);
2436+
error = -EPROTONOSUPPORT;
2437+
goto out_err;
2438+
default:
2439+
trace_rpc__unparsable(task);
2440+
error = -EIO;
2441+
goto out_err;
2442+
}
2443+
2444+
switch (*p++) {
2445+
case rpc_autherr_rejectedcred:
2446+
case rpc_autherr_rejectedverf:
2447+
case rpcsec_gsserr_credproblem:
2448+
case rpcsec_gsserr_ctxproblem:
2449+
if (!task->tk_cred_retry)
2450+
break;
2451+
task->tk_cred_retry--;
2452+
trace_rpc__stale_creds(task);
2453+
rpcauth_invalcred(task);
2454+
/* Ensure we obtain a new XID! */
2455+
xprt_release(task);
2456+
task->tk_action = call_reserve;
2457+
return ERR_PTR(-EAGAIN);
2458+
case rpc_autherr_badcred:
2459+
case rpc_autherr_badverf:
2460+
/* possibly garbled cred/verf? */
2461+
if (!task->tk_garb_retry)
2462+
break;
2463+
task->tk_garb_retry--;
2464+
trace_rpc__bad_creds(task);
2465+
task->tk_action = call_encode;
2466+
return ERR_PTR(-EAGAIN);
2467+
case rpc_autherr_tooweak:
2468+
trace_rpc__auth_tooweak(task);
2469+
pr_warn("RPC: server %s requires stronger authentication.\n",
2470+
task->tk_xprt->servername);
2471+
break;
2472+
default:
2473+
trace_rpc__unparsable(task);
2474+
error = -EIO;
2475+
}
2476+
goto out_err;
25082477
}
25092478

25102479
static void rpcproc_encode_null(struct rpc_rqst *rqstp, struct xdr_stream *xdr,

0 commit comments

Comments
 (0)