static inline int at_get(struct adaptive_timeout *at) {
return at->at_current;
}
-int at_add(struct adaptive_timeout *at, unsigned int val);
+int at_measured(struct adaptive_timeout *at, unsigned int val);
int import_at_get_index(struct obd_import *imp, int portal);
extern unsigned int at_max;
#define AT_OFF (at_max == 0)
if (!new_client && service_time)
/* Teach server about old server's estimates, as first guess
* at how long new requests will take. */
- at_add(&req->rq_rqbd->rqbd_service->srv_at_estimate,
- service_time);
+ at_measured(&req->rq_rqbd->rqbd_service->srv_at_estimate,
+ service_time);
check_and_start_recovery_timer(obd);
/* Server-side enqueue wait time estimate, used in
__ldlm_add_waiting_lock to set future enqueue timers */
if (total_enqueue_wait < ldlm_get_enq_timeout(lock))
- at_add(&lock->l_resource->lr_namespace->ns_at_estimate,
- total_enqueue_wait);
+ at_measured(&lock->l_resource->lr_namespace->ns_at_estimate,
+ total_enqueue_wait);
else
/* bz18618. Don't add lock enqueue time we spend waiting for a
previous callback to fail. Locks waiting legitimately will
CFS_DURATION_T"s", delay);
/* Update our time estimate */
- at_add(&lock->l_resource->lr_namespace->ns_at_estimate, delay);
+ at_measured(&lock->l_resource->lr_namespace->ns_at_estimate,
+ delay);
result = 0;
}
return result;
idx = import_at_get_index(req->rq_import, req->rq_request_portal);
/* max service estimates are tracked on the server side,
so just keep minimal history here */
- oldse = at_add(&at->iat_service_estimate[idx], serv_est);
+ oldse = at_measured(&at->iat_service_estimate[idx], serv_est);
if (oldse != 0)
CDEBUG(D_ADAPTTO, "The RPC service estimate for %s ptl %d "
"has changed from %d to %d\n",
CFS_DURATION_T"\n", service_time,
cfs_time_sub(now, req->rq_sent));
- oldnl = at_add(&at->iat_net_latency, nl);
+ oldnl = at_measured(&at->iat_net_latency, nl);
if (oldnl != 0)
CDEBUG(D_ADAPTTO, "The network latency for %s (nid %s) "
"has changed from %d to %d\n",
!imp->imp_recon_bk /* not retrying */) {
if (at_get(&imp->imp_at.iat_net_latency) <
CONNECTION_SWITCH_MAX) {
- at_add(&imp->imp_at.iat_net_latency,
- at_get(&imp->imp_at.iat_net_latency) +
- CONNECTION_SWITCH_INC);
+ at_measured(&imp->imp_at.iat_net_latency,
+ at_get(&imp->imp_at.iat_net_latency) +
+ CONNECTION_SWITCH_INC);
}
LASSERT(imp_conn->oic_last_attempt);
CWARN("%s: tried all connections, increasing latency to %ds\n",
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.) */
-int at_add(struct adaptive_timeout *at, unsigned int val)
+int at_measured(struct adaptive_timeout *at, unsigned int val)
{
unsigned int old = at->at_current;
time_t now = cfs_time_current_sec();
MSG_REQ_REPLAY_DONE | MSG_LOCK_REPLAY_DONE))) {
/* early replies, errors and recovery requests don't count
* toward our service time estimate */
- int oldse = at_add(&svc->srv_at_estimate, service_time);
+ int oldse = at_measured(&svc->srv_at_estimate, service_time);
if (oldse != 0)
DEBUG_REQ(D_ADAPTTO, req,
"svc %s changed estimate from %d to %d",
if (req->rq_export &&
lustre_msg_get_flags(req->rq_reqmsg) &
(MSG_REPLAY | MSG_REQ_REPLAY_DONE | MSG_LOCK_REPLAY_DONE)) {
- /**
- * Use at_extra as early reply period for recovery requests but
- * make sure it is not bigger than recovery time / 4
- */
- at_add(&svc->srv_at_estimate,
- min(at_extra,
- req->rq_export->exp_obd->obd_recovery_timeout / 4));
+ /* During recovery, we don't want to send too many early
+ * replies, but on the other hand we want to make sure the
+ * client has enough time to resend if the rpc is lost. So
+ * during the recovery period send at least 4 early replies,
+ * spacing them every at_extra if we can. at_estimate should
+ * always equal this fixed value during recovery. */
+ at_measured(&svc->srv_at_estimate, min(at_extra,
+ req->rq_export->exp_obd->obd_recovery_timeout / 4));
} else {
/* Fake our processing time into the future to ask the clients
* for some extra amount of time */
- at_add(&svc->srv_at_estimate, at_extra);
+ at_measured(&svc->srv_at_estimate, at_extra +
+ cfs_time_current_sec() -
+ req->rq_arrival_time.tv_sec);
+
+ /* Check to see if we've actually increased the deadline -
+ * we may be past adaptive_max */
+ if (req->rq_deadline >= req->rq_arrival_time.tv_sec +
+ at_get(&svc->srv_at_estimate)) {
+ DEBUG_REQ(D_WARNING, req, "Couldn't add any time "
+ "(%ld/%ld), not sending early reply\n",
+ olddl, req->rq_arrival_time.tv_sec +
+ at_get(&svc->srv_at_estimate) -
+ cfs_time_current_sec());
+ RETURN(-ETIMEDOUT);
+ }
}
-
newdl = cfs_time_current_sec() + at_get(&svc->srv_at_estimate);
- if (req->rq_deadline >= newdl) {
- /* We're not adding any time, no need to send an early reply
- (e.g. maybe at adaptive_max) */
- DEBUG_REQ(D_WARNING, req, "Couldn't add any time ("
- CFS_DURATION_T"/"CFS_DURATION_T"), "
- "not sending early reply\n", olddl,
- cfs_time_sub(newdl, cfs_time_current_sec()));
- RETURN(-ETIMEDOUT);
- }
OBD_ALLOC(reqcopy, sizeof *reqcopy);
if (reqcopy == NULL)