__u32 pb_op_flags;
__u32 pb_conn_cnt;
__u32 pb_timeout; /* for req, the deadline, for rep, the service est */
- __u32 pb_service_time; /* for rep, actual service time */
+ __u32 pb_service_time; /* for rep, actual service time, also used for
+ net_latency of req */
__u32 pb_limit;
__u64 pb_slv;
/* VBR: pre-versions */
* Add request timeout to the recovery time so next request from
* this client may come in recovery time
*/
- if (!AT_OFF)
- to = lustre_msg_get_timeout(req->rq_reqmsg);
- extend_recovery_timer(class_exp2obd(req->rq_export), to);
+ if (!AT_OFF) {
+ struct ptlrpc_service *svc = req->rq_rqbd->rqbd_service;
+ /* If the server sent early reply for this request,
+ * the client will recalculate the timeout according to
+ * current server estimate service time, so we will
+ * use the maxium timeout here for waiting the client
+ * sending the next req */
+ to = max((int)at_est2timeout(
+ at_get(&svc->srv_at_estimate)),
+ (int)lustre_msg_get_timeout(req->rq_reqmsg));
+ /* Add net_latency (see ptlrpc_replay_req) */
+ to += lustre_msg_get_service_time(req->rq_reqmsg);
+ }
+ extend_recovery_timer(class_exp2obd(req->rq_export), to);
}
reqcopy_put:
RETURN(rc);
/* Readjust the timeout for current conditions */
ptlrpc_at_set_req_timeout(req);
+ /* Tell server the net_latency, so the server can calculate how long
+ * it should wait for next replay */
+ lustre_msg_set_service_time(req->rq_reqmsg,
+ ptlrpc_at_get_net_latency(req));
DEBUG_REQ(D_HA, req, "REPLAY");
cfs_atomic_inc(&req->rq_import->imp_replay_inflight);