out:
        spin_lock(&xprt->recv_lock);
        cwnd = xprt->cwnd;
-       xprt->cwnd = atomic_read(&r_xprt->rx_buf.rb_credits) << RPC_CWNDSHIFT;
+       xprt->cwnd = r_xprt->rx_buf.rb_credits << RPC_CWNDSHIFT;
        if (xprt->cwnd > cwnd)
                xprt_release_rqst_cong(rqst->rq_task);
 
 {
        struct rpcrdma_xprt *r_xprt = rep->rr_rxprt;
        struct rpc_xprt *xprt = &r_xprt->rx_xprt;
+       struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
        struct rpcrdma_req *req;
        struct rpc_rqst *rqst;
+       u32 credits;
        __be32 *p;
 
        dprintk("RPC:       %s: incoming rep %p\n", __func__, rep);
                goto out_shortreply;
        rep->rr_xid = *p++;
        rep->rr_vers = *p++;
-       p++;    /* credits */
+       credits = be32_to_cpu(*p++);
        rep->rr_proc = *p++;
 
        if (rep->rr_vers != rpcrdma_version)
        if (!rqst)
                goto out_norqst;
        xprt_pin_rqst(rqst);
+
+       if (credits == 0)
+               credits = 1;    /* don't deadlock */
+       else if (credits > buf->rb_max_requests)
+               credits = buf->rb_max_requests;
+       buf->rb_credits = credits;
+
        spin_unlock(&xprt->recv_lock);
+
        req = rpcr_to_rdmar(rqst);
        req->rl_reply = rep;
        rep->rr_rqst = rqst;
 
                       wc->status, wc->vendor_err);
 }
 
-/* Perform basic sanity checking to avoid using garbage
- * to update the credit grant value.
- */
-static void
-rpcrdma_update_granted_credits(struct rpcrdma_rep *rep)
-{
-       struct rpcrdma_buffer *buffer = &rep->rr_rxprt->rx_buf;
-       __be32 *p = rep->rr_rdmabuf->rg_base;
-       u32 credits;
-
-       credits = be32_to_cpup(p + 2);
-       if (credits == 0)
-               credits = 1;    /* don't deadlock */
-       else if (credits > buffer->rb_max_requests)
-               credits = buffer->rb_max_requests;
-
-       atomic_set(&buffer->rb_credits, credits);
-}
-
 /**
  * rpcrdma_wc_receive - Invoked by RDMA provider for each polled Receive WC
  * @cq:        completion queue (ignored)
                                   rdmab_addr(rep->rr_rdmabuf),
                                   wc->byte_len, DMA_FROM_DEVICE);
 
-       if (wc->byte_len >= RPCRDMA_HDRLEN_ERR)
-               rpcrdma_update_granted_credits(rep);
-
 out_schedule:
        rpcrdma_reply_handler(rep);
        return;
        case RDMA_CM_EVENT_DISCONNECTED:
                connstate = -ECONNABORTED;
 connected:
-               atomic_set(&xprt->rx_buf.rb_credits, 1);
+               xprt->rx_buf.rb_credits = 1;
                ep->rep_connected = connstate;
                rpcrdma_conn_func(ep);
                wake_up_all(&ep->rep_connect_wait);
 
        buf->rb_max_requests = r_xprt->rx_data.max_requests;
        buf->rb_bc_srv_max_requests = 0;
-       atomic_set(&buf->rb_credits, 1);
        spin_lock_init(&buf->rb_mwlock);
        spin_lock_init(&buf->rb_lock);
        spin_lock_init(&buf->rb_recovery_lock);