Commit 31c5e95e authored by Chris Horn's avatar Chris Horn Committed by Greg Kroah-Hartman

staging: lustre: ptlrpc: Early replies need to honor at_max

When determining whether an early reply can be sent the server will
calculate the new deadline based on an offset from the request
arrival time. However, when actually setting the new deadline
the server offsets the current time. This can result in deadlines
being extended more than at_max seconds past the request arrival
time. Instead, the server should offset the arrival time when updating
its request timeout.

When a client receives an early reply it doesn't know the server side
arrival time so we use the original sent time as an approximation.
Signed-off-by: default avatarChris Horn <hornc@cray.com>
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-4578
Reviewed-on: http://review.whamcloud.com/9100Reviewed-by: default avatarJames Simmons <uja.ornl@gmail.com>
Reviewed-by: default avatarChristopher J. Morrone <chris.morrone.llnl@gmail.com>
Reviewed-by: default avatarOleg Drokin <oleg.drokin@intel.com>
Signed-off-by: default avatarJames Simmons <jsimmons@infradead.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c3397e7e
...@@ -385,10 +385,12 @@ static int ptlrpc_at_recv_early_reply(struct ptlrpc_request *req) ...@@ -385,10 +385,12 @@ static int ptlrpc_at_recv_early_reply(struct ptlrpc_request *req)
spin_lock(&req->rq_lock); spin_lock(&req->rq_lock);
olddl = req->rq_deadline; olddl = req->rq_deadline;
/* /*
* server assumes it now has rq_timeout from when it sent the * server assumes it now has rq_timeout from when the request
* early reply, so client should give it at least that long. * arrived, so the client should give it at least that long.
* since we don't know the arrival time we'll use the original
* sent time
*/ */
req->rq_deadline = ktime_get_real_seconds() + req->rq_timeout + req->rq_deadline = req->rq_sent + req->rq_timeout +
ptlrpc_at_get_net_latency(req); ptlrpc_at_get_net_latency(req);
DEBUG_REQ(D_ADAPTTO, req, DEBUG_REQ(D_ADAPTTO, req,
......
...@@ -1497,10 +1497,13 @@ EXPORT_SYMBOL(ptlrpc_disconnect_import); ...@@ -1497,10 +1497,13 @@ EXPORT_SYMBOL(ptlrpc_disconnect_import);
/* Adaptive Timeout utils */ /* Adaptive Timeout utils */
extern unsigned int at_min, at_max, at_history; extern unsigned int at_min, at_max, at_history;
/* Bin into timeslices using AT_BINS bins. /*
* This gives us a max of the last binlimit*AT_BINS secs without the storage, *Update at_current with the specified value (bounded by at_min and at_max),
* as well as the AT history "bins".
* - Bin into timeslices using AT_BINS bins.
* - This gives us a max of the last at_history seconds without the storage,
* but still smoothing out a return to normalcy from a slow response. * but still smoothing out a return to normalcy from a slow response.
* (E.g. remember the maximum latency in each minute of the last 4 minutes.) * - (E.g. remember the maximum latency in each minute of the last 4 minutes.)
*/ */
int at_measured(struct adaptive_timeout *at, unsigned int val) int at_measured(struct adaptive_timeout *at, unsigned int val)
{ {
......
...@@ -1005,13 +1005,16 @@ ptlrpc_at_remove_timed(struct ptlrpc_request *req) ...@@ -1005,13 +1005,16 @@ ptlrpc_at_remove_timed(struct ptlrpc_request *req)
array->paa_count--; array->paa_count--;
} }
/*
* Attempt to extend the request deadline by sending an early reply to the
* client.
*/
static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req) static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req)
{ {
struct ptlrpc_service_part *svcpt = req->rq_rqbd->rqbd_svcpt; struct ptlrpc_service_part *svcpt = req->rq_rqbd->rqbd_svcpt;
struct ptlrpc_request *reqcopy; struct ptlrpc_request *reqcopy;
struct lustre_msg *reqmsg; struct lustre_msg *reqmsg;
long olddl = req->rq_deadline - ktime_get_real_seconds(); long olddl = req->rq_deadline - ktime_get_real_seconds();
time64_t newdl;
int rc; int rc;
/* deadline is when the client expects us to reply, margin is the /* deadline is when the client expects us to reply, margin is the
...@@ -1039,8 +1042,13 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req) ...@@ -1039,8 +1042,13 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req)
return -ENOSYS; return -ENOSYS;
} }
/* Fake our processing time into the future to ask the clients /*
* for some extra amount of time * We want to extend the request deadline by at_extra seconds,
* so we set our service estimate to reflect how much time has
* passed since this request arrived plus an additional
* at_extra seconds. The client will calculate the new deadline
* based on this service estimate (plus some additional time to
* account for network latency). See ptlrpc_at_recv_early_reply
*/ */
at_measured(&svcpt->scp_at_estimate, at_extra + at_measured(&svcpt->scp_at_estimate, at_extra +
ktime_get_real_seconds() - req->rq_arrival_time.tv_sec); ktime_get_real_seconds() - req->rq_arrival_time.tv_sec);
...@@ -1056,7 +1064,6 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req) ...@@ -1056,7 +1064,6 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req)
ktime_get_real_seconds()); ktime_get_real_seconds());
return -ETIMEDOUT; return -ETIMEDOUT;
} }
newdl = ktime_get_real_seconds() + at_get(&svcpt->scp_at_estimate);
reqcopy = ptlrpc_request_cache_alloc(GFP_NOFS); reqcopy = ptlrpc_request_cache_alloc(GFP_NOFS);
if (!reqcopy) if (!reqcopy)
...@@ -1110,7 +1117,8 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req) ...@@ -1110,7 +1117,8 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req)
if (!rc) { if (!rc) {
/* Adjust our own deadline to what we told the client */ /* Adjust our own deadline to what we told the client */
req->rq_deadline = newdl; req->rq_deadline = req->rq_arrival_time.tv_sec +
at_get(&svcpt->scp_at_estimate);
req->rq_early_count++; /* number sent, server side */ req->rq_early_count++; /* number sent, server side */
} else { } else {
DEBUG_REQ(D_ERROR, req, "Early reply send failed %d", rc); DEBUG_REQ(D_ERROR, req, "Early reply send failed %d", rc);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment