]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
SUNRPC: receive buffer size estimation values almost never change
authorChuck Lever <chuck.lever@oracle.com>
Tue, 12 May 2020 21:13:01 +0000 (17:13 -0400)
committerAnna Schumaker <Anna.Schumaker@Netapp.com>
Thu, 11 Jun 2020 17:33:47 +0000 (13:33 -0400)
Avoid unnecessary cache sloshing by placing the buffer size
estimation update logic behind an atomic bit flag.

The size of GSS information included in each wrapped Reply does
not change during the lifetime of a GSS context. Therefore, the
au_rslack and au_ralign fields need to be updated only once after
establishing a fresh GSS credential.

Thus a slack size update must occur after a cred is created,
duplicated, renewed, or expires. I'm not sure I have this exactly
right. A trace point is introduced to track updates to these
variables to enable troubleshooting the problem if I missed a spot.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
include/linux/sunrpc/auth.h
include/trace/events/rpcgss.h
net/sunrpc/auth_gss/auth_gss.c
net/sunrpc/xprtrdma/rpc_rdma.c

index 4f6b28487f280071213f157985f9afc580caa5c6..98da816b5fc2ad064355f0baba1f13d43afe799a 100644 (file)
@@ -76,7 +76,7 @@ struct rpc_auth {
        unsigned int            au_verfsize;    /* size of reply verifier */
        unsigned int            au_ralign;      /* words before UL header */
 
-       unsigned int            au_flags;
+       unsigned long           au_flags;
        const struct rpc_authops *au_ops;
        rpc_authflavor_t        au_flavor;      /* pseudoflavor (note may
                                                 * differ from the flavor in
@@ -89,7 +89,8 @@ struct rpc_auth {
 };
 
 /* rpc_auth au_flags */
-#define RPCAUTH_AUTH_DATATOUCH 0x00000002
+#define RPCAUTH_AUTH_DATATOUCH         (1)
+#define RPCAUTH_AUTH_UPDATE_SLACK      (2)
 
 struct rpc_auth_create_args {
        rpc_authflavor_t pseudoflavor;
index 32d88c4fb0630ced100615340f625473c6e6a219..421b14db87ae32a251526b5436f5cbbdcdd05568 100644 (file)
@@ -291,6 +291,40 @@ TRACE_EVENT(rpcgss_need_reencode,
                __entry->ret ? "" : "un")
 );
 
+TRACE_EVENT(rpcgss_update_slack,
+       TP_PROTO(
+               const struct rpc_task *task,
+               const struct rpc_auth *auth
+       ),
+
+       TP_ARGS(task, auth),
+
+       TP_STRUCT__entry(
+               __field(unsigned int, task_id)
+               __field(unsigned int, client_id)
+               __field(u32, xid)
+               __field(const void *, auth)
+               __field(unsigned int, rslack)
+               __field(unsigned int, ralign)
+               __field(unsigned int, verfsize)
+       ),
+
+       TP_fast_assign(
+               __entry->task_id = task->tk_pid;
+               __entry->client_id = task->tk_client->cl_clid;
+               __entry->xid = be32_to_cpu(task->tk_rqstp->rq_xid);
+               __entry->auth = auth;
+               __entry->rslack = auth->au_rslack;
+               __entry->ralign = auth->au_ralign;
+               __entry->verfsize = auth->au_verfsize;
+       ),
+
+       TP_printk("task:%u@%u xid=0x%08x auth=%p rslack=%u ralign=%u verfsize=%u\n",
+               __entry->task_id, __entry->client_id, __entry->xid,
+               __entry->auth, __entry->rslack, __entry->ralign,
+               __entry->verfsize)
+);
+
 DECLARE_EVENT_CLASS(rpcgss_svc_seqno_class,
        TP_PROTO(
                __be32 xid,
index ac5cac0dd24b98edcc6cff89ab174329131de7c9..5f097c8cacd1bc83586cf5056f545a4e788ab6e2 100644 (file)
@@ -1054,11 +1054,11 @@ gss_create_new(const struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
        auth->au_rslack = GSS_KRB5_MAX_SLACK_NEEDED >> 2;
        auth->au_verfsize = GSS_VERF_SLACK >> 2;
        auth->au_ralign = GSS_VERF_SLACK >> 2;
-       auth->au_flags = 0;
+       __set_bit(RPCAUTH_AUTH_UPDATE_SLACK, &auth->au_flags);
        auth->au_ops = &authgss_ops;
        auth->au_flavor = flavor;
        if (gss_pseudoflavor_to_datatouch(gss_auth->mech, flavor))
-               auth->au_flags |= RPCAUTH_AUTH_DATATOUCH;
+               __set_bit(RPCAUTH_AUTH_DATATOUCH, &auth->au_flags);
        refcount_set(&auth->au_count, 1);
        kref_init(&gss_auth->kref);
 
@@ -1613,6 +1613,7 @@ static int gss_renew_cred(struct rpc_task *task)
        new = gss_lookup_cred(auth, &acred, RPCAUTH_LOOKUP_NEW);
        if (IS_ERR(new))
                return PTR_ERR(new);
+
        task->tk_rqstp->rq_cred = new;
        put_rpccred(oldcred);
        return 0;
@@ -1709,7 +1710,8 @@ gss_validate(struct rpc_task *task, struct xdr_stream *xdr)
 
        /* We leave it to unwrap to calculate au_rslack. For now we just
         * calculate the length of the verifier: */
-       cred->cr_auth->au_verfsize = XDR_QUADLEN(len) + 2;
+       if (test_bit(RPCAUTH_AUTH_UPDATE_SLACK, &cred->cr_auth->au_flags))
+               cred->cr_auth->au_verfsize = XDR_QUADLEN(len) + 2;
        status = 0;
 out:
        gss_put_ctx(ctx);
@@ -1927,13 +1929,30 @@ out:
        return status;
 }
 
-static int
-gss_unwrap_resp_auth(struct rpc_cred *cred)
+/**
+ * gss_update_rslack - Possibly update RPC receive buffer size estimates
+ * @task: rpc_task for incoming RPC Reply being unwrapped
+ * @cred: controlling rpc_cred for @task
+ * @before: XDR words needed before each RPC Reply message
+ * @after: XDR words needed following each RPC Reply message
+ *
+ */
+static void gss_update_rslack(struct rpc_task *task, struct rpc_cred *cred,
+                             unsigned int before, unsigned int after)
 {
        struct rpc_auth *auth = cred->cr_auth;
 
-       auth->au_rslack = auth->au_verfsize;
-       auth->au_ralign = auth->au_verfsize;
+       if (test_and_clear_bit(RPCAUTH_AUTH_UPDATE_SLACK, &auth->au_flags)) {
+               auth->au_ralign = auth->au_verfsize + before;
+               auth->au_rslack = auth->au_verfsize + after;
+               trace_rpcgss_update_slack(task, auth);
+       }
+}
+
+static int
+gss_unwrap_resp_auth(struct rpc_task *task, struct rpc_cred *cred)
+{
+       gss_update_rslack(task, cred, 0, 0);
        return 0;
 }
 
@@ -1956,7 +1975,6 @@ gss_unwrap_resp_integ(struct rpc_task *task, struct rpc_cred *cred,
                      struct xdr_stream *xdr)
 {
        struct xdr_buf gss_data, *rcv_buf = &rqstp->rq_rcv_buf;
-       struct rpc_auth *auth = cred->cr_auth;
        u32 len, offset, seqno, maj_stat;
        struct xdr_netobj mic;
        int ret;
@@ -2005,8 +2023,7 @@ gss_unwrap_resp_integ(struct rpc_task *task, struct rpc_cred *cred,
        if (maj_stat != GSS_S_COMPLETE)
                goto bad_mic;
 
-       auth->au_rslack = auth->au_verfsize + 2 + 1 + XDR_QUADLEN(mic.len);
-       auth->au_ralign = auth->au_verfsize + 2;
+       gss_update_rslack(task, cred, 2, 2 + 1 + XDR_QUADLEN(mic.len));
        ret = 0;
 
 out:
@@ -2031,7 +2048,6 @@ gss_unwrap_resp_priv(struct rpc_task *task, struct rpc_cred *cred,
 {
        struct xdr_buf *rcv_buf = &rqstp->rq_rcv_buf;
        struct kvec *head = rqstp->rq_rcv_buf.head;
-       struct rpc_auth *auth = cred->cr_auth;
        u32 offset, opaque_len, maj_stat;
        __be32 *p;
 
@@ -2058,8 +2074,8 @@ gss_unwrap_resp_priv(struct rpc_task *task, struct rpc_cred *cred,
         */
        xdr_init_decode(xdr, rcv_buf, p, rqstp);
 
-       auth->au_rslack = auth->au_verfsize + 2 + ctx->gc_gss_ctx->slack;
-       auth->au_ralign = auth->au_verfsize + 2 + ctx->gc_gss_ctx->align;
+       gss_update_rslack(task, cred, 2 + ctx->gc_gss_ctx->align,
+                         2 + ctx->gc_gss_ctx->slack);
 
        return 0;
 unwrap_failed:
@@ -2130,7 +2146,7 @@ gss_unwrap_resp(struct rpc_task *task, struct xdr_stream *xdr)
                goto out_decode;
        switch (gss_cred->gc_service) {
        case RPC_GSS_SVC_NONE:
-               status = gss_unwrap_resp_auth(cred);
+               status = gss_unwrap_resp_auth(task, cred);
                break;
        case RPC_GSS_SVC_INTEGRITY:
                status = gss_unwrap_resp_integ(task, cred, ctx, rqstp, xdr);
index 3c627dc685cc85e5f415e2248d2ac95d416b84c4..2081c8fbfa48d5f3a553bfecf4feb15f0459978f 100644 (file)
@@ -892,8 +892,8 @@ rpcrdma_marshal_req(struct rpcrdma_xprt *r_xprt, struct rpc_rqst *rqst)
         * or privacy, direct data placement of individual data items
         * is not allowed.
         */
-       ddp_allowed = !(rqst->rq_cred->cr_auth->au_flags &
-                                               RPCAUTH_AUTH_DATATOUCH);
+       ddp_allowed = !test_bit(RPCAUTH_AUTH_DATATOUCH,
+                               &rqst->rq_cred->cr_auth->au_flags);
 
        /*
         * Chunks needed for results?