[PATCH] RPC: add a release_rqst callout to the RPC transport switch
The final place where congestion control state is adjusted is in xprt_release, where each request is finally released. Add a callout there to allow transports to perform additional processing when a request is about to be released. Test-plan: Use WAN simulation to cause sporadic bursty packet loss. Look for significant regression in performance or client stability. Signed-off-by: Chuck Lever <cel@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
parent
1570c1e41e
commit
a58dd398f5
|
@ -138,6 +138,7 @@ struct rpc_xprt_ops {
|
||||||
int (*send_request)(struct rpc_task *task);
|
int (*send_request)(struct rpc_task *task);
|
||||||
void (*set_retrans_timeout)(struct rpc_task *task);
|
void (*set_retrans_timeout)(struct rpc_task *task);
|
||||||
void (*timer)(struct rpc_task *task);
|
void (*timer)(struct rpc_task *task);
|
||||||
|
void (*release_request)(struct rpc_task *task);
|
||||||
void (*close)(struct rpc_xprt *xprt);
|
void (*close)(struct rpc_xprt *xprt);
|
||||||
void (*destroy)(struct rpc_xprt *xprt);
|
void (*destroy)(struct rpc_xprt *xprt);
|
||||||
};
|
};
|
||||||
|
@ -262,6 +263,7 @@ void xprt_update_rtt(struct rpc_task *task);
|
||||||
void xprt_adjust_cwnd(struct rpc_task *task, int result);
|
void xprt_adjust_cwnd(struct rpc_task *task, int result);
|
||||||
struct rpc_rqst * xprt_lookup_rqst(struct rpc_xprt *xprt, u32 xid);
|
struct rpc_rqst * xprt_lookup_rqst(struct rpc_xprt *xprt, u32 xid);
|
||||||
void xprt_complete_rqst(struct rpc_task *task, int copied);
|
void xprt_complete_rqst(struct rpc_task *task, int copied);
|
||||||
|
void xprt_release_rqst_cong(struct rpc_task *task);
|
||||||
void xprt_disconnect(struct rpc_xprt *xprt);
|
void xprt_disconnect(struct rpc_xprt *xprt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -289,6 +289,17 @@ __xprt_put_cong(struct rpc_xprt *xprt, struct rpc_rqst *req)
|
||||||
__xprt_lock_write_next_cong(xprt);
|
__xprt_lock_write_next_cong(xprt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xprt_release_rqst_cong - housekeeping when request is complete
|
||||||
|
* @task: RPC request that recently completed
|
||||||
|
*
|
||||||
|
* Useful for transports that require congestion control.
|
||||||
|
*/
|
||||||
|
void xprt_release_rqst_cong(struct rpc_task *task)
|
||||||
|
{
|
||||||
|
__xprt_put_cong(task->tk_xprt, task->tk_rqstp);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xprt_adjust_cwnd - adjust transport congestion window
|
* xprt_adjust_cwnd - adjust transport congestion window
|
||||||
* @task: recently completed RPC request used to adjust window
|
* @task: recently completed RPC request used to adjust window
|
||||||
|
@ -823,7 +834,8 @@ void xprt_release(struct rpc_task *task)
|
||||||
return;
|
return;
|
||||||
spin_lock_bh(&xprt->transport_lock);
|
spin_lock_bh(&xprt->transport_lock);
|
||||||
xprt->ops->release_xprt(xprt, task);
|
xprt->ops->release_xprt(xprt, task);
|
||||||
__xprt_put_cong(xprt, req);
|
if (xprt->ops->release_request)
|
||||||
|
xprt->ops->release_request(task);
|
||||||
if (!list_empty(&req->rq_list))
|
if (!list_empty(&req->rq_list))
|
||||||
list_del(&req->rq_list);
|
list_del(&req->rq_list);
|
||||||
xprt->last_used = jiffies;
|
xprt->last_used = jiffies;
|
||||||
|
|
|
@ -1059,6 +1059,7 @@ static struct rpc_xprt_ops xs_udp_ops = {
|
||||||
.send_request = xs_udp_send_request,
|
.send_request = xs_udp_send_request,
|
||||||
.set_retrans_timeout = xprt_set_retrans_timeout_rtt,
|
.set_retrans_timeout = xprt_set_retrans_timeout_rtt,
|
||||||
.timer = xs_udp_timer,
|
.timer = xs_udp_timer,
|
||||||
|
.release_request = xprt_release_rqst_cong,
|
||||||
.close = xs_close,
|
.close = xs_close,
|
||||||
.destroy = xs_destroy,
|
.destroy = xs_destroy,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue