[PATCH] sunrpc: drop BKL around wrap and unwrap

J. Bruce Fields bfields at fieldses.org
Tue Jul 10 18:13:05 EDT 2007


From: J. Bruce Fields <bfields at citi.umich.edu>

We don't need the BKL when wrapping and unwrapping; and experiments by Avishay
Traeger have found that permitting multiple encryption and decryption
operations to proceed in parallel can provide significant performance
improvements.

Signed-off-by: J. Bruce Fields <bfields at citi.umich.edu>
Cc: Avishay Traeger <atraeger at cs.sunysb.edu>
---
 net/sunrpc/auth.c              |   12 ++++++++++--
 net/sunrpc/auth_gss/auth_gss.c |   10 ++++++++++
 net/sunrpc/clnt.c              |    4 ----
 3 files changed, 20 insertions(+), 6 deletions(-)

On Tue, Jul 10, 2007 at 05:37:12PM -0400, Trond Myklebust wrote:
> Vetoed until you fix rpcauth_wrap_req()/rpcauth_unwrap_resp().

Oops--you're talking about the missed bkl around the encode/decode
invocations there?  How about this?

--b.

diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index 9527f2b..e04da66 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -359,13 +359,17 @@ rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp,
 		__be32 *data, void *obj)
 {
 	struct rpc_cred *cred = task->tk_msg.rpc_cred;
+	int ret;
 
 	dprintk("RPC: %5u using %s cred %p to wrap rpc data\n",
 			task->tk_pid, cred->cr_ops->cr_name, cred);
 	if (cred->cr_ops->crwrap_req)
 		return cred->cr_ops->crwrap_req(task, encode, rqstp, data, obj);
 	/* By default, we encode the arguments normally. */
-	return encode(rqstp, data, obj);
+	lock_kernel();
+	ret = encode(rqstp, data, obj);
+	unlock_kernel();
+	return ret;
 }
 
 int
@@ -373,6 +377,7 @@ rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp,
 		__be32 *data, void *obj)
 {
 	struct rpc_cred *cred = task->tk_msg.rpc_cred;
+	int ret;
 
 	dprintk("RPC: %5u using %s cred %p to unwrap rpc data\n",
 			task->tk_pid, cred->cr_ops->cr_name, cred);
@@ -380,7 +385,10 @@ rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp,
 		return cred->cr_ops->crunwrap_resp(task, decode, rqstp,
 						   data, obj);
 	/* By default, we decode the arguments normally. */
-	return decode(rqstp, data, obj);
+	lock_kernel();
+	ret = decode(rqstp, data, obj);
+	unlock_kernel();
+	return ret;
 }
 
 int
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 4e4ccc5..a001973 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -917,7 +917,9 @@ gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
 	offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base;
 	*p++ = htonl(rqstp->rq_seqno);
 
+	lock_kernel();
 	status = encode(rqstp, p, obj);
+	unlock_kernel();
 	if (status)
 		return status;
 
@@ -1011,7 +1013,9 @@ gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
 	offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base;
 	*p++ = htonl(rqstp->rq_seqno);
 
+	lock_kernel();
 	status = encode(rqstp, p, obj);
+	unlock_kernel();
 	if (status)
 		return status;
 
@@ -1070,12 +1074,16 @@ gss_wrap_req(struct rpc_task *task,
 		/* The spec seems a little ambiguous here, but I think that not
 		 * wrapping context destruction requests makes the most sense.
 		 */
+		lock_kernel();
 		status = encode(rqstp, p, obj);
+		unlock_kernel();
 		goto out;
 	}
 	switch (gss_cred->gc_service) {
 		case RPC_GSS_SVC_NONE:
+			lock_kernel();
 			status = encode(rqstp, p, obj);
+			unlock_kernel();
 			break;
 		case RPC_GSS_SVC_INTEGRITY:
 			status = gss_wrap_req_integ(cred, ctx, encode,
@@ -1191,7 +1199,9 @@ gss_unwrap_resp(struct rpc_task *task,
 	task->tk_auth->au_rslack = task->tk_auth->au_verfsize + (p - savedp)
 						+ (savedlen - head->iov_len);
 out_decode:
+	lock_kernel();
 	status = decode(rqstp, p, obj);
+	unlock_kernel();
 out:
 	gss_put_ctx(ctx);
 	dprintk("RPC: %5u gss_unwrap_resp returning %d\n", task->tk_pid,
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index d8fbee4..2534690 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -843,10 +843,8 @@ call_encode(struct rpc_task *task)
 	if (encode == NULL)
 		return;
 
-	lock_kernel();
 	task->tk_status = rpcauth_wrap_req(task, encode, req, p,
 			task->tk_msg.rpc_argp);
-	unlock_kernel();
 	if (task->tk_status == -ENOMEM) {
 		/* XXX: Is this sane? */
 		rpc_delay(task, 3*HZ);
@@ -1177,10 +1175,8 @@ call_decode(struct rpc_task *task)
 	task->tk_action = rpc_exit_task;
 
 	if (decode) {
-		lock_kernel();
 		task->tk_status = rpcauth_unwrap_resp(task, decode, req, p,
 						      task->tk_msg.rpc_resp);
-		unlock_kernel();
 	}
 	dprintk("RPC: %5u call_decode result %d\n", task->tk_pid,
 			task->tk_status);
-- 
1.5.2.58.g98ee



More information about the NFSv4 mailing list