mirror of https://gitee.com/openkylin/linux.git
xprtrdma: Decode credits field in rpcrdma_reply_handler
We need to decode and save the incoming rdma_credits field _after_ we know that the direction of the message is "forward direction Reply". Otherwise, the credits value in reverse direction Calls is also used to update the forward direction credits. It is safe to decode the rdma_credits field in rpcrdma_reply_handler now that rpcrdma_reply_handler is single-threaded. Receives complete in the same order as they were sent on the NFS server. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
parent
d8f532d20e
commit
be798f9082
|
@ -1244,7 +1244,7 @@ void rpcrdma_complete_rqst(struct rpcrdma_rep *rep)
|
|||
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);
|
||||
|
||||
|
@ -1297,8 +1297,10 @@ void rpcrdma_reply_handler(struct rpcrdma_rep *rep)
|
|||
{
|
||||
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);
|
||||
|
@ -1315,7 +1317,7 @@ void rpcrdma_reply_handler(struct rpcrdma_rep *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)
|
||||
|
@ -1332,7 +1334,15 @@ void rpcrdma_reply_handler(struct rpcrdma_rep *rep)
|
|||
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;
|
||||
|
|
|
@ -133,25 +133,6 @@ rpcrdma_wc_send(struct ib_cq *cq, struct ib_wc *wc)
|
|||
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)
|
||||
|
@ -181,9 +162,6 @@ rpcrdma_wc_receive(struct ib_cq *cq, struct ib_wc *wc)
|
|||
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;
|
||||
|
@ -295,7 +273,7 @@ rpcrdma_conn_upcall(struct rdma_cm_id *id, struct rdma_cm_event *event)
|
|||
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);
|
||||
|
@ -995,7 +973,6 @@ rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt)
|
|||
|
||||
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);
|
||||
|
|
|
@ -407,7 +407,7 @@ struct rpcrdma_buffer {
|
|||
struct list_head rb_send_bufs;
|
||||
struct list_head rb_recv_bufs;
|
||||
u32 rb_max_requests;
|
||||
atomic_t rb_credits; /* most recent credit grant */
|
||||
u32 rb_credits; /* most recent credit grant */
|
||||
|
||||
u32 rb_bc_srv_max_requests;
|
||||
spinlock_t rb_reqslock; /* protect rb_allreqs */
|
||||
|
|
Loading…
Reference in New Issue