diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c index 549c62c93fbe..f2e71b40b16d 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/client.c +++ b/drivers/staging/lustre/lustre/ptlrpc/client.c @@ -385,10 +385,12 @@ static int ptlrpc_at_recv_early_reply(struct ptlrpc_request *req) spin_lock(&req->rq_lock); olddl = req->rq_deadline; /* - * server assumes it now has rq_timeout from when it sent the - * early reply, so client should give it at least that long. + * server assumes it now has rq_timeout from when the request + * 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); DEBUG_REQ(D_ADAPTTO, req, diff --git a/drivers/staging/lustre/lustre/ptlrpc/import.c b/drivers/staging/lustre/lustre/ptlrpc/import.c index 3292e6ea0102..af8ffbc90f66 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/import.c +++ b/drivers/staging/lustre/lustre/ptlrpc/import.c @@ -1497,10 +1497,13 @@ EXPORT_SYMBOL(ptlrpc_disconnect_import); /* Adaptive Timeout utils */ 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, - * 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.) +/* + *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. + * - (E.g. remember the maximum latency in each minute of the last 4 minutes.) */ int at_measured(struct adaptive_timeout *at, unsigned int val) { diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c index 4788c4940c2a..30d8b72cdf74 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/service.c +++ b/drivers/staging/lustre/lustre/ptlrpc/service.c @@ -1005,13 +1005,16 @@ ptlrpc_at_remove_timed(struct ptlrpc_request *req) 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) { struct ptlrpc_service_part *svcpt = req->rq_rqbd->rqbd_svcpt; struct ptlrpc_request *reqcopy; struct lustre_msg *reqmsg; long olddl = req->rq_deadline - ktime_get_real_seconds(); - time64_t newdl; int rc; /* 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) 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 + 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) ktime_get_real_seconds()); return -ETIMEDOUT; } - newdl = ktime_get_real_seconds() + at_get(&svcpt->scp_at_estimate); reqcopy = ptlrpc_request_cache_alloc(GFP_NOFS); if (!reqcopy) @@ -1110,7 +1117,8 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req) if (!rc) { /* 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 */ } else { DEBUG_REQ(D_ERROR, req, "Early reply send failed %d", rc);