Skip to content

Commit

Permalink
SUNRPC: Improve latency for interactive tasks
Browse files Browse the repository at this point in the history
One of the intentions with the priority queues was to ensure that no
single process can hog the transport. The field task->tk_owner therefore
identifies the RPC call's origin, and is intended to allow the RPC layer
to organise queues for fairness.
This commit therefore modifies the transmit queue to group requests
by task->tk_owner, and ensures that we round robin among those groups.

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
  • Loading branch information
Trond Myklebust committed Sep 30, 2018
1 parent dcbbeda commit 918f3c1
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 3 deletions.
1 change: 1 addition & 0 deletions include/linux/sunrpc/xprt.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ struct rpc_rqst {
};

struct list_head rq_xmit; /* Send queue */
struct list_head rq_xmit2; /* Send queue */

void *rq_buffer; /* Call XDR encode buffer */
size_t rq_callsize;
Expand Down
27 changes: 24 additions & 3 deletions net/sunrpc/xprt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1053,12 +1053,21 @@ xprt_request_need_enqueue_transmit(struct rpc_task *task, struct rpc_rqst *req)
void
xprt_request_enqueue_transmit(struct rpc_task *task)
{
struct rpc_rqst *req = task->tk_rqstp;
struct rpc_rqst *pos, *req = task->tk_rqstp;
struct rpc_xprt *xprt = req->rq_xprt;

if (xprt_request_need_enqueue_transmit(task, req)) {
spin_lock(&xprt->queue_lock);
list_for_each_entry(pos, &xprt->xmit_queue, rq_xmit) {
if (pos->rq_task->tk_owner != task->tk_owner)
continue;
list_add_tail(&req->rq_xmit2, &pos->rq_xmit2);
INIT_LIST_HEAD(&req->rq_xmit);
goto out;
}
list_add_tail(&req->rq_xmit, &xprt->xmit_queue);
INIT_LIST_HEAD(&req->rq_xmit2);
out:
set_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate);
spin_unlock(&xprt->queue_lock);
}
Expand All @@ -1074,8 +1083,20 @@ xprt_request_enqueue_transmit(struct rpc_task *task)
static void
xprt_request_dequeue_transmit_locked(struct rpc_task *task)
{
if (test_and_clear_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate))
list_del(&task->tk_rqstp->rq_xmit);
struct rpc_rqst *req = task->tk_rqstp;

if (!test_and_clear_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate))
return;
if (!list_empty(&req->rq_xmit)) {
list_del(&req->rq_xmit);
if (!list_empty(&req->rq_xmit2)) {
struct rpc_rqst *next = list_first_entry(&req->rq_xmit2,
struct rpc_rqst, rq_xmit2);
list_del(&req->rq_xmit2);
list_add_tail(&next->rq_xmit, &next->rq_xprt->xmit_queue);
}
} else
list_del(&req->rq_xmit2);
}

/**
Expand Down

0 comments on commit 918f3c1

Please sign in to comment.