* The resources in this namespace remember contended state during
* \a ns_contention_time, in seconds.
*/
- time64_t ns_contention_time;
+ timeout_t ns_contention_time;
/**
* Limit size of contended extent locks, in bytes.
* under this lock.
* \see ost_rw_prolong_locks
*/
- time64_t l_callback_timeout;
+ time64_t l_callback_timestamp;
/** Local PID of process which created this lock. */
__u32 l_pid;
struct ldlm_res_id lpa_resid;
struct ldlm_extent lpa_extent;
enum ldlm_mode lpa_mode;
- time64_t lpa_timeout;
+ timeout_t lpa_timeout;
int lpa_locks_cnt;
int lpa_blocks_cnt;
};
/** @} ldlm_handlers */
void ldlm_revoke_export_locks(struct obd_export *exp);
-time64_t ldlm_bl_timeout(struct ldlm_lock *lock);
+timeout_t ldlm_bl_timeout(struct ldlm_lock *lock);
#endif
int ldlm_del_waiting_lock(struct ldlm_lock *lock);
-int ldlm_refresh_waiting_lock(struct ldlm_lock *lock, time64_t timeout);
+int ldlm_refresh_waiting_lock(struct ldlm_lock *lock, timeout_t timeout);
int ldlm_get_ref(void);
void ldlm_put_ref(void);
int ldlm_init_export(struct obd_export *exp);
time64_t at_binstart; /* bin start time */
unsigned int at_hist[AT_BINS]; /* timeout history bins */
unsigned int at_flags;
- unsigned int at_current; /* current timeout value */
- unsigned int at_worst_ever; /* worst-ever timeout value */
- time64_t at_worst_time; /* worst-ever timeout timestamp */
+ timeout_t at_current_timeout; /* current timeout value */
+ timeout_t at_worst_timeout_ever; /* worst-ever timeout delta
+ * value
+ */
+ time64_t at_worst_timestamp; /* worst-ever timeout
+ * timestamp
+ */
spinlock_t at_lock;
};
time64_t imp_last_reply_time; /* for health check */
};
-/* import.c */
-static inline unsigned int at_est2timeout(unsigned int val)
+/* import.c : adaptive timeout handling.
+ *
+ * Lustre tracks how long RPCs take to complete. This information is reported
+ * back to clients who utilize the information to estimate the time needed
+ * for future requests and set appropriate RPC timeouts. Minimum and maximum
+ * service times can be configured via the at_min and at_max kernel module
+ * parameters, respectively.
+ *
+ * Since this information is transmitted between nodes the timeouts are in
+ * seconds not jiffies which can vary from node to node. To avoid confusion
+ * the timeout is handled in timeout_t (s32) instead of time64_t or
+ * long (jiffies).
+ */
+static inline timeout_t at_est2timeout(timeout_t timeout)
{
- /* add an arbitrary minimum: 125% +5 sec */
- return (val + (val >> 2) + 5);
+ /* add an arbitrary minimum: 125% +5 sec */
+ return timeout + (timeout >> 2) + 5;
}
static inline timeout_t at_timeout2est(timeout_t timeout)
return max((timeout << 2) / 5, 5) - 4;
}
-static inline void at_reset_nolock(struct adaptive_timeout *at, int val)
+static inline void at_reset_nolock(struct adaptive_timeout *at,
+ timeout_t timeout)
{
- at->at_current = val;
- at->at_worst_ever = val;
- at->at_worst_time = ktime_get_real_seconds();
+ at->at_current_timeout = timeout;
+ at->at_worst_timeout_ever = timeout;
+ at->at_worst_timestamp = ktime_get_real_seconds();
}
-static inline void at_reset(struct adaptive_timeout *at, int val)
+static inline void at_reset(struct adaptive_timeout *at, timeout_t timeout)
{
spin_lock(&at->at_lock);
- at_reset_nolock(at, val);
+ at_reset_nolock(at, timeout);
spin_unlock(&at->at_lock);
}
-static inline void at_init(struct adaptive_timeout *at, int val, int flags) {
+static inline void at_init(struct adaptive_timeout *at, timeout_t timeout,
+ int flags)
+{
memset(at, 0, sizeof(*at));
spin_lock_init(&at->at_lock);
at->at_flags = flags;
- at_reset(at, val);
+ at_reset(at, timeout);
}
-static inline void at_reinit(struct adaptive_timeout *at, int val, int flags)
+static inline void at_reinit(struct adaptive_timeout *at, timeout_t timeout,
+ int flags)
{
spin_lock(&at->at_lock);
at->at_binstart = 0;
memset(at->at_hist, 0, sizeof(at->at_hist));
at->at_flags = flags;
- at_reset_nolock(at, val);
+ at_reset_nolock(at, timeout);
spin_unlock(&at->at_lock);
}
extern unsigned int at_min;
-static inline int at_get(struct adaptive_timeout *at) {
- return (at->at_current > at_min) ? at->at_current : at_min;
-}
-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)
+static inline timeout_t at_get(struct adaptive_timeout *at)
+{
+ return (at->at_current_timeout > at_min) ?
+ at->at_current_timeout : at_min;
+}
+
+timeout_t at_measured(struct adaptive_timeout *at, timeout_t timeout);
+int import_at_get_index(struct obd_import *imp, int portal);
+
/* genops.c */
struct obd_export;
extern struct obd_import *class_exp2cliimp(struct obd_export *);
struct ptlrpc_cli_req {
/** For bulk requests on client only: bulk descriptor */
struct ptlrpc_bulk_desc *cr_bulk;
- /** optional time limit for send attempts */
- time64_t cr_delay_limit;
+ /** optional time limit for send attempts. This is a timeout
+ * not a timestamp so timeout_t (s32) is used instead of time64_t
+ */
+ timeout_t cr_delay_limit;
/** time request was first queued */
time64_t cr_queued_time;
/** request sent in nanoseconds */
max_t(int, at, obd_timeout);
}
+/**
+ * Calculate the amount of time for lock prolongation.
+ *
+ * This is helper function to get the timeout extra time.
+ *
+ * @req current request
+ *
+ * Return: amount of time to extend the timeout with
+ */
+static inline timeout_t prolong_timeout(struct ptlrpc_request *req)
+{
+ struct ptlrpc_service_part *svcpt = req->rq_rqbd->rqbd_svcpt;
+ timeout_t req_timeout = 0;
+
+ if (AT_OFF)
+ return obd_timeout / 2;
+
+ if (req->rq_deadline > req->rq_arrival_time.tv_sec)
+ req_timeout = req->rq_deadline - req->rq_arrival_time.tv_sec;
+
+ return max(req_timeout,
+ at_est2timeout(at_get(&svcpt->scp_at_estimate)));
+}
+
static inline struct ptlrpc_service *
ptlrpc_req2svc(struct ptlrpc_request *req)
{
time64_t obd_recovery_start;
/* seconds, for lprocfs_status */
time64_t obd_recovery_end;
- /* To tell timeouts from time stamps Lustre uses time_t
+ /* To tell timeouts from time stamps Lustre uses timeout_t
* instead of time64_t.
*/
- time_t obd_recovery_time_hard;
- time_t obd_recovery_timeout;
- int obd_recovery_ir_factor;
+ timeout_t obd_recovery_time_hard;
+ timeout_t obd_recovery_timeout;
+ int obd_recovery_ir_factor;
/* new recovery stuff from CMD2 */
int obd_replayed_locks;
}
}
-static int ldlm_check_contention(struct ldlm_lock *lock, int contended_locks)
+static bool ldlm_check_contention(struct ldlm_lock *lock, int contended_locks)
{
struct ldlm_resource *res = lock->l_resource;
time64_t now = ktime_get_seconds();
if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_SET_CONTENTION))
- return 1;
+ return true;
CDEBUG(D_DLMTRACE, "contended locks = %d\n", contended_locks);
if (contended_locks > ldlm_res_to_ns(res)->ns_contended_locks)
void ldlm_lock_prolong_one(struct ldlm_lock *lock,
struct ldlm_prolong_args *arg)
{
- time64_t timeout;
+ timeout_t timeout;
OBD_FAIL_TIMEOUT(OBD_FAIL_LDLM_PROLONG_PAUSE, 3);
*/
timeout = arg->lpa_timeout + (ldlm_bl_timeout(lock) >> 1);
- LDLM_DEBUG(lock, "refreshed to %llds.\n", timeout);
+ LDLM_DEBUG(lock, "refreshed to %ds.\n", timeout);
arg->lpa_blocks_cnt++;
elapsed_time = max_t(time64_t, now - obd->obd_recovery_start,
1);
LCONSOLE_INFO("%s: Recovery over after %lld:%.02lld, of %d clients %d recovered and %d %s evicted.\n",
- obd->obd_name, (s64)elapsed_time / 60,
- (s64)elapsed_time % 60,
+ obd->obd_name, elapsed_time / 60,
+ elapsed_time % 60,
atomic_read(&obd->obd_max_recoverable_clients),
atomic_read(&obd->obd_connected_clients),
obd->obd_stale_clients,
hrtimer_start(&obd->obd_recovery_timer, delay, HRTIMER_MODE_ABS);
spin_unlock(&obd->obd_dev_lock);
- LCONSOLE_WARN("%s: Will be in recovery for at least %lu:%02lu, or until %d client%s reconnect%s\n",
+ LCONSOLE_WARN("%s: Will be in recovery for at least %u:%02u, or until %d client%s reconnect%s\n",
obd->obd_name,
obd->obd_recovery_timeout / 60,
obd->obd_recovery_timeout % 60,
* at least; otherwise, make sure the recovery timeout value is not less
* than @dr_timeout.
*/
-static void extend_recovery_timer(struct obd_device *obd, time_t dr_timeout,
+static void extend_recovery_timer(struct obd_device *obd, timeout_t dr_timeout,
bool extend)
{
ktime_t left_ns;
- time_t timeout;
- time_t left;
+ timeout_t timeout;
+ timeout_t left;
spin_lock(&obd->obd_dev_lock);
if (!obd->obd_recovering || obd->obd_abort_recovery ||
*/
if (dr_timeout > left) {
timeout += dr_timeout - left;
- timeout = min_t(time_t, obd->obd_recovery_time_hard,
+ timeout = min_t(timeout_t, obd->obd_recovery_time_hard,
timeout);
}
} else {
- timeout = clamp_t(time_t, dr_timeout, obd->obd_recovery_timeout,
+ timeout = clamp_t(timeout_t, dr_timeout,
+ obd->obd_recovery_timeout,
obd->obd_recovery_time_hard);
}
if (timeout == obd->obd_recovery_time_hard)
- CWARN("%s: extended recovery timer reached hard limit: %ld, extend: %d\n",
+ CWARN("%s: extended recovery timer reached hard limit: %d, extend: %d\n",
obd->obd_name, timeout, extend);
if (obd->obd_recovery_timeout < timeout) {
}
spin_unlock(&obd->obd_dev_lock);
- CDEBUG(D_HA, "%s: recovery timer will expire in %ld seconds\n",
+ CDEBUG(D_HA, "%s: recovery timer will expire in %d seconds\n",
obd->obd_name, left);
}
extend_recovery_timer(obd, obd->obd_recovery_timeout,
true);
CDEBUG(D_HA,
- "%s update recovery is not ready, extend recovery %lu\n",
+ "%s update recovery is not ready, extend recovery %d\n",
obd->obd_name, obd->obd_recovery_timeout);
return 0;
}
lu_ref_init(&lock->l_reference);
lu_ref_add(&lock->l_reference, "hash", lock);
- lock->l_callback_timeout = 0;
+ lock->l_callback_timestamp = 0;
lock->l_activity = 0;
#if LUSTRE_TRACKS_LOCK_EXP_REFS
lock->l_flags, nid,
lock->l_remote_handle.cookie,
exp ? refcount_read(&exp->exp_handle.h_ref) : -99,
- lock->l_pid, lock->l_callback_timeout,
+ lock->l_pid, lock->l_callback_timestamp,
lock->l_lvb_type);
va_end(args);
return;
lock->l_flags, nid,
lock->l_remote_handle.cookie,
exp ? refcount_read(&exp->exp_handle.h_ref) : -99,
- lock->l_pid, lock->l_callback_timeout,
+ lock->l_pid, lock->l_callback_timestamp,
lock->l_lvb_type);
break;
lock->l_flags, nid,
lock->l_remote_handle.cookie,
exp ? refcount_read(&exp->exp_handle.h_ref) : -99,
- lock->l_pid, lock->l_callback_timeout);
+ lock->l_pid, lock->l_callback_timestamp);
break;
case LDLM_IBITS:
lock->l_flags, nid,
lock->l_remote_handle.cookie,
exp ? refcount_read(&exp->exp_handle.h_ref) : -99,
- lock->l_pid, lock->l_callback_timeout,
+ lock->l_pid, lock->l_callback_timestamp,
lock->l_lvb_type);
break;
lock->l_flags, nid,
lock->l_remote_handle.cookie,
exp ? refcount_read(&exp->exp_handle.h_ref) : -99,
- lock->l_pid, lock->l_callback_timeout,
+ lock->l_pid, lock->l_callback_timestamp,
lock->l_lvb_type);
break;
}
static LIST_HEAD(expired_lock_list);
static int ldlm_lock_busy(struct ldlm_lock *lock);
-static int ldlm_add_waiting_lock(struct ldlm_lock *lock, time64_t timeout);
-static int __ldlm_add_waiting_lock(struct ldlm_lock *lock, time64_t seconds);
+static int ldlm_add_waiting_lock(struct ldlm_lock *lock, timeout_t timeout);
+static int __ldlm_add_waiting_lock(struct ldlm_lock *lock, timeout_t timeout);
static inline int have_expired_locks(void)
{
/* Check if we need to prolong timeout */
if (!OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_HPREQ_TIMEOUT) &&
- lock->l_callback_timeout != 0 && /* not AST error */
+ lock->l_callback_timestamp != 0 && /* not AST error */
ldlm_lock_busy(lock)) {
LDLM_DEBUG(lock, "prolong the busy lock");
lock_res_and_lock(lock);
while (!list_empty(&waiting_locks_list)) {
lock = list_entry(waiting_locks_list.next, struct ldlm_lock,
l_pending_chain);
- if (lock->l_callback_timeout > ktime_get_seconds() ||
+ if (lock->l_callback_timestamp > ktime_get_seconds() ||
lock->l_req_mode == LCK_GROUP)
break;
*/
if (!list_empty(&waiting_locks_list)) {
time64_t now = ktime_get_seconds();
- time_t delta = 0;
+ timeout_t delta = 0;
lock = list_entry(waiting_locks_list.next, struct ldlm_lock,
l_pending_chain);
- if (lock->l_callback_timeout - now > 0)
- delta = lock->l_callback_timeout - now;
+ if (lock->l_callback_timestamp - now > 0)
+ delta = lock->l_callback_timestamp - now;
mod_timer(&waiting_locks_timer,
jiffies + cfs_time_seconds(delta));
}
*
* Called with the namespace lock held.
*/
-static int __ldlm_add_waiting_lock(struct ldlm_lock *lock, time64_t seconds)
+static int __ldlm_add_waiting_lock(struct ldlm_lock *lock, timeout_t delay)
{
unsigned long timeout_jiffies = jiffies;
time64_t now = ktime_get_seconds();
time64_t deadline;
- time_t timeout;
+ timeout_t timeout;
if (!list_empty(&lock->l_pending_chain))
return 0;
if (OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_HPREQ_NOTIMEOUT) ||
OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_HPREQ_TIMEOUT))
- seconds = 1;
+ delay = 1;
- deadline = now + seconds;
- if (likely(deadline > lock->l_callback_timeout))
- lock->l_callback_timeout = deadline;
+ deadline = now + delay;
+ if (likely(deadline > lock->l_callback_timestamp))
+ lock->l_callback_timestamp = deadline;
- timeout = clamp_t(time_t, lock->l_callback_timeout - now,
- 0, seconds);
+ timeout = clamp_t(timeout_t, lock->l_callback_timestamp - now,
+ 0, delay);
timeout_jiffies += cfs_time_seconds(timeout);
if (time_before(timeout_jiffies, waiting_locks_timer.expires) ||
obd_stale_export_adjust(lock->l_export);
}
-static int ldlm_add_waiting_lock(struct ldlm_lock *lock, time64_t timeout)
+static int ldlm_add_waiting_lock(struct ldlm_lock *lock, timeout_t timeout)
{
int ret;
if (ret)
ldlm_add_blocked_lock(lock);
- LDLM_DEBUG(lock, "%sadding to wait list(timeout: %lld, AT: %s)",
+ LDLM_DEBUG(lock, "%sadding to wait list(timeout: %d, AT: %s)",
ret == 0 ? "not re-" : "", timeout,
AT_OFF ? "off" : "on");
return ret;
} else {
time64_t now = ktime_get_seconds();
struct ldlm_lock *next;
- time_t delta = 0;
+ timeout_t delta = 0;
next = list_entry(list_next, struct ldlm_lock,
l_pending_chain);
- if (next->l_callback_timeout - now > 0)
- delta = lock->l_callback_timeout - now;
+ if (next->l_callback_timestamp - now > 0)
+ delta = lock->l_callback_timestamp - now;
mod_timer(&waiting_locks_timer,
jiffies + cfs_time_seconds(delta));
*
* Called with namespace lock held.
*/
-int ldlm_refresh_waiting_lock(struct ldlm_lock *lock, time64_t timeout)
+int ldlm_refresh_waiting_lock(struct ldlm_lock *lock, timeout_t timeout)
{
if (lock->l_export == NULL) {
/* We don't have a "waiting locks list" on clients. */
RETURN(0);
}
-int ldlm_refresh_waiting_lock(struct ldlm_lock *lock, time64_t timeout)
+int ldlm_refresh_waiting_lock(struct ldlm_lock *lock, timeout_t timeout)
{
RETURN(0);
}
*
* \retval timeout in seconds to wait for the client reply
*/
-time64_t ldlm_bl_timeout(struct ldlm_lock *lock)
+timeout_t ldlm_bl_timeout(struct ldlm_lock *lock)
{
- time64_t timeout;
+ timeout_t timeout;
if (AT_OFF)
return obd_timeout / 2;
* lock callbacks too...
*/
timeout = at_get(&lock->l_export->exp_bl_lock_at);
- return max(timeout + (timeout >> 1), (time64_t)ldlm_enqueue_min);
+ return max_t(timeout_t, timeout + (timeout >> 1),
+ (timeout_t)ldlm_enqueue_min);
}
EXPORT_SYMBOL(ldlm_bl_timeout);
* the lock to the expired list
*/
LDLM_LOCK_GET(lock);
- lock->l_callback_timeout = 0; /* differentiate it from expired locks */
+ /* differentiate it from expired locks */
+ lock->l_callback_timestamp = 0;
list_add(&lock->l_pending_chain, &expired_lock_list);
wake_up(&expired_lock_wait_queue);
spin_unlock_bh(&waiting_locks_spinlock);
if ((flags & LATF_STATS) && ldlm_is_ast_sent(lock) &&
lock->l_blast_sent != 0) {
- time64_t delay = ktime_get_real_seconds() -
- lock->l_blast_sent;
+ timeout_t delay = 0;
+
+ if (ktime_get_real_seconds() > lock->l_blast_sent)
+ delay = ktime_get_real_seconds() -
+ lock->l_blast_sent;
LDLM_DEBUG(lock,
- "server cancels blocked lock after %llds",
- (s64)delay);
+ "server cancels blocked lock after %ds",
+ delay);
at_measured(&lock->l_export->exp_bl_lock_at, delay);
}
ldlm_lock_cancel(lock);
LDLM_ERROR(lock,
"lock timed out (enqueued at %lld, %llds ago); not entering recovery in server code, just going back to sleep",
- (s64)lock->l_activity,
- (s64)(ktime_get_real_seconds() -
- lock->l_activity));
+ lock->l_activity,
+ ktime_get_real_seconds() - lock->l_activity);
if (ktime_get_seconds() > next_dump) {
last_dump = next_dump;
next_dump = ktime_get_seconds() + 300;
ptlrpc_fail_import(imp, lwd->lwd_conn_cnt);
LDLM_ERROR(lock,
"lock timed out (enqueued at %lld, %llds ago), entering recovery for %s@%s",
- (s64)lock->l_activity,
- (s64)(ktime_get_real_seconds() - lock->l_activity),
+ lock->l_activity,
+ ktime_get_real_seconds() - lock->l_activity,
obd2cli_tgt(obd), imp->imp_connection->c_remote_uuid.uuid);
EXIT;
* We use the same basis for both server side and client side functions
* from a single node.
*/
-static time64_t ldlm_cp_timeout(struct ldlm_lock *lock)
+static timeout_t ldlm_cp_timeout(struct ldlm_lock *lock)
{
- time64_t timeout;
+ timeout_t timeout;
if (AT_OFF)
return obd_timeout;
* doesn't respond reasonably, and then give us the lock.
*/
timeout = at_get(ldlm_lock_to_ns_at(lock));
- return max(3 * timeout, (time64_t) ldlm_enqueue_min);
+ return max(3 * timeout, (timeout_t)ldlm_enqueue_min);
}
/**
*/
static int ldlm_completion_tail(struct ldlm_lock *lock, void *data)
{
- time64_t delay;
int result = 0;
if (ldlm_is_destroyed(lock) || ldlm_is_failed(lock)) {
LDLM_DEBUG(lock, "client-side enqueue: granted");
} else {
/* Take into AT only CP RPC, not immediately granted locks */
- delay = ktime_get_real_seconds() - lock->l_activity;
- LDLM_DEBUG(lock, "client-side enqueue: granted after %llds",
- (s64)delay);
+ timeout_t delay = 0;
+ /* Discard negative timeouts. We should also limit the
+ * maximum value of the timeout
+ */
+ if (ktime_get_real_seconds() > lock->l_activity)
+ delay = ktime_get_real_seconds() - lock->l_activity;
+
+ LDLM_DEBUG(lock, "client-side enqueue: granted after %ds",
+ delay);
/* Update our time estimate */
at_measured(ldlm_lock_to_ns_at(lock), delay);
}
struct lock_wait_data lwd;
struct obd_device *obd;
struct obd_import *imp = NULL;
- time64_t timeout;
+ timeout_t timeout;
int rc = 0;
ENTRY;
struct ldlm_namespace *ns = container_of(kobj, struct ldlm_namespace,
ns_kobj);
- return sprintf(buf, "%llu\n", ns->ns_contention_time);
+ return scnprintf(buf, PAGE_SIZE, "%d\n", ns->ns_contention_time);
}
static ssize_t contention_seconds_store(struct kobject *kobj,
{
struct ldlm_namespace *ns = container_of(kobj, struct ldlm_namespace,
ns_kobj);
- unsigned long long tmp;
+ unsigned int tmp;
- if (kstrtoull(buffer, 10, &tmp))
+ if (kstrtouint(buffer, 10, &tmp))
return -EINVAL;
ns->ns_contention_time = tmp;
* first as we assume they could be idle since longer
*/
if (rec->cur_time != 0) {
- __u32 time_now = (__u32)ktime_get_real_seconds();
- __u32 time_out = rec->cur_time +
- mdd->mdd_changelog_max_idle_time;
- __u32 idle_time = time_now - rec->cur_time;
+ /* FIXME !!!! cur_time is a timestamp but only 32 bit in
+ * in size. This is not 2038 safe !!!!
+ */
+ u32 time_now = (u32)ktime_get_real_seconds();
+ timeout_t time_out = rec->cur_time +
+ mdd->mdd_changelog_max_idle_time;
+ timeout_t idle_time = time_now - rec->cur_time;
/* treat oldest idle user first, and if no old format user
* has been already selected
* list */
struct mutex cdt_restore_lock; /**< protect restore
* list */
- s32 cdt_loop_period; /**< llog scan period */
- s32 cdt_grace_delay; /**< request grace
+ timeout_t cdt_loop_period; /**< llog scan period */
+ timeout_t cdt_grace_delay; /**< request grace
* delay */
- s32 cdt_active_req_timeout; /**< request timeout */
+ timeout_t cdt_active_req_timeout; /**< request timeout */
__u32 cdt_default_archive_id; /**< archive id used
* when none are
* specified */
up_write(&mo->mot_dom_sem);
}
-/**
- * Lock prolongation for Data-on-MDT.
- * This is similar to OFD code but for DOM ibits lock.
- */
-static inline time64_t prolong_timeout(struct ptlrpc_request *req)
-{
- struct ptlrpc_service_part *svcpt = req->rq_rqbd->rqbd_svcpt;
- time64_t req_timeout;
-
- if (AT_OFF)
- return obd_timeout / 2;
-
- req_timeout = req->rq_deadline - req->rq_arrival_time.tv_sec;
- return max_t(time64_t, at_est2timeout(at_get(&svcpt->scp_at_estimate)),
- req_timeout);
-}
-
static void mdt_dom_resource_prolong(struct ldlm_prolong_args *arg)
{
struct ldlm_resource *res;
}
seq_printf(m, " service_estimates:\n"
" services: %u sec\n"
- " network: %u sec\n",
+ " network: %d sec\n",
k,
at_get(&imp->imp_at.iat_net_latency));
struct obd_device *obd,
struct obd_import *imp)
{
- unsigned int cur, worst;
- time64_t now, worstt;
+ timeout_t cur_timeout, worst_timeout;
+ time64_t now, worst_timestamp;
int i;
LASSERT(obd != NULL);
"last reply", (s64)imp->imp_last_reply_time,
(s64)(now - imp->imp_last_reply_time));
- cur = at_get(&imp->imp_at.iat_net_latency);
- worst = imp->imp_at.iat_net_latency.at_worst_ever;
- worstt = imp->imp_at.iat_net_latency.at_worst_time;
+ cur_timeout = at_get(&imp->imp_at.iat_net_latency);
+ worst_timeout = imp->imp_at.iat_net_latency.at_worst_timeout_ever;
+ worst_timestamp = imp->imp_at.iat_net_latency.at_worst_timestamp;
seq_printf(m, "%-10s : cur %3u worst %3u (at %lld, %llds ago) ",
- "network", cur, worst, (s64)worstt, (s64)(now - worstt));
+ "network", cur_timeout, worst_timeout, worst_timestamp,
+ now - worst_timestamp);
lprocfs_at_hist_helper(m, &imp->imp_at.iat_net_latency);
for(i = 0; i < IMP_AT_MAX_PORTALS; i++) {
+ struct adaptive_timeout *service_est;
+
if (imp->imp_at.iat_portal[i] == 0)
break;
- cur = at_get(&imp->imp_at.iat_service_estimate[i]);
- worst = imp->imp_at.iat_service_estimate[i].at_worst_ever;
- worstt = imp->imp_at.iat_service_estimate[i].at_worst_time;
+
+ service_est = &imp->imp_at.iat_service_estimate[i];
+ cur_timeout = at_get(service_est);
+ worst_timeout = service_est->at_worst_timeout_ever;
+ worst_timestamp = service_est->at_worst_timestamp;
seq_printf(m, "portal %-2d : cur %3u worst %3u (at %lld, %llds ago) ",
- imp->imp_at.iat_portal[i], cur, worst, (s64)worstt,
- (s64)(now - worstt));
- lprocfs_at_hist_helper(m, &imp->imp_at.iat_service_estimate[i]);
+ imp->imp_at.iat_portal[i], cur_timeout,
+ worst_timeout, worst_timestamp,
+ now - worst_timestamp);
+ lprocfs_at_hist_helper(m, service_est);
}
}
struct obd_device *obd = container_of(kobj, struct obd_device,
obd_kset.kobj);
- return scnprintf(buf, PAGE_SIZE, "%ld\n", obd->obd_recovery_timeout);
+ return scnprintf(buf, PAGE_SIZE, "%d\n", obd->obd_recovery_timeout);
}
EXPORT_SYMBOL(recovery_time_soft_show);
struct obd_device *obd = container_of(kobj, struct obd_device,
obd_kset.kobj);
- return scnprintf(buf, PAGE_SIZE, "%ld\n", obd->obd_recovery_time_hard);
+ return scnprintf(buf, PAGE_SIZE, "%d\n", obd->obd_recovery_time_hard);
}
EXPORT_SYMBOL(recovery_time_hard_show);
}
/**
- * Calculate the amount of time for lock prolongation.
- *
- * This is helper for ofd_prolong_extent_locks() function to get
- * the timeout extra time.
- *
- * \param[in] req current request
- *
- * \retval amount of time to extend the timeout with
- */
-static inline time64_t prolong_timeout(struct ptlrpc_request *req)
-{
- struct ptlrpc_service_part *svcpt = req->rq_rqbd->rqbd_svcpt;
- time64_t req_timeout;
-
- if (AT_OFF)
- return obd_timeout / 2;
-
- req_timeout = req->rq_deadline - req->rq_arrival_time.tv_sec;
- return max_t(time64_t, at_est2timeout(at_get(&svcpt->scp_at_estimate)),
- req_timeout);
-}
-
-/**
* Prolong lock timeout for the given extent.
*
* This function finds all locks related with incoming request and
*/
void ptlrpc_at_set_req_timeout(struct ptlrpc_request *req)
{
- __u32 serv_est;
- int idx;
- struct imp_at *at;
-
LASSERT(req->rq_import);
if (AT_OFF) {
req->rq_timeout = req->rq_import->imp_server_timeout ?
obd_timeout / 2 : obd_timeout;
} else {
- at = &req->rq_import->imp_at;
+ struct imp_at *at = &req->rq_import->imp_at;
+ timeout_t serv_est;
+ int idx;
+
idx = import_at_get_index(req->rq_import,
req->rq_request_portal);
serv_est = at_get(&at->iat_service_estimate[idx]);
+ /*
+ * Currently a 32 bit value is sent over the
+ * wire for rq_timeout so please don't change this
+ * to time64_t. The work for LU-1158 will in time
+ * replace rq_timeout with a 64 bit nanosecond value
+ */
req->rq_timeout = at_est2timeout(serv_est);
}
/*
* We could get even fancier here, using history to predict increased
* loading...
- */
-
- /*
+ *
* Let the server know what this RPC timeout is by putting it in the
* reqmsg
*/
/* Adjust max service estimate based on server value */
static void ptlrpc_at_adj_service(struct ptlrpc_request *req,
- unsigned int serv_est)
+ timeout_t serv_est)
{
int idx;
- unsigned int oldse;
+ timeout_t oldse;
struct imp_at *at;
LASSERT(req->rq_import);
void ptlrpc_at_adj_net_latency(struct ptlrpc_request *req,
timeout_t service_timeout)
{
- unsigned int nl, oldnl;
- struct imp_at *at;
time64_t now = ktime_get_real_seconds();
+ struct imp_at *at;
+ timeout_t oldnl;
+ timeout_t nl;
LASSERT(req->rq_import);
return;
}
- /* Network latency is total time less server processing time */
- nl = max_t(int, now - req->rq_sent -
- service_timeout, 0) + 1; /* st rounding */
+ /* Network latency is total time less server processing time,
+ * st rounding
+ */
+ nl = max_t(timeout_t, now - req->rq_sent - service_timeout, 0) + 1;
at = &req->rq_import->imp_at;
oldnl = at_measured(&at->iat_net_latency, nl);
req->rq_real_sent < req->rq_sent ||
req->rq_real_sent >= req->rq_deadline) ?
"timed out for sent delay" : "timed out for slow reply"),
- (s64)req->rq_sent, (s64)req->rq_real_sent);
+ req->rq_sent, req->rq_real_sent);
if (imp && obd_debug_peer_on_timeout)
LNetDebugPeer(imp->imp_connection->c_peer);
*/
if (tried_all && (imp->imp_conn_list.next == &imp_conn->oic_item)) {
struct adaptive_timeout *at = &imp->imp_at.iat_net_latency;
+
if (at_get(at) < CONNECTION_SWITCH_MAX) {
at_measured(at, at_get(at) + CONNECTION_SWITCH_INC);
if (at_get(at) > CONNECTION_SWITCH_MAX)
at_reset(at, CONNECTION_SWITCH_MAX);
}
LASSERT(imp_conn->oic_last_attempt);
- CDEBUG(D_HA, "%s: tried all connections, increasing latency "
- "to %ds\n", imp->imp_obd->obd_name, at_get(at));
+ CDEBUG(D_HA,
+ "%s: tried all connections, increasing latency to %ds\n",
+ imp->imp_obd->obd_name, at_get(at));
}
imp_conn->oic_last_attempt = ktime_get_seconds();
/* Adaptive Timeout utils */
-/* Update at_current with the specified value (bounded by at_min and at_max),
- * as well as the AT history "bins".
+/* Update at_current_timeout 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)
+timeout_t at_measured(struct adaptive_timeout *at, timeout_t timeout)
{
- unsigned int old = at->at_current;
+ timeout_t old_timeout = at->at_current_timeout;
time64_t now = ktime_get_real_seconds();
long binlimit = max_t(long, at_history / AT_BINS, 1);
LASSERT(at);
- CDEBUG(D_OTHER, "add %u to %p time=%lu v=%u (%u %u %u %u)\n",
- val, at, (long)(now - at->at_binstart), at->at_current,
+ CDEBUG(D_OTHER, "add %u to %p time=%lld v=%u (%u %u %u %u)\n",
+ timeout, at, now - at->at_binstart, at->at_current_timeout,
at->at_hist[0], at->at_hist[1], at->at_hist[2], at->at_hist[3]);
- if (val == 0)
- /* 0's don't count, because we never want our timeout to
- drop to 0, and because 0 could mean an error */
+ if (timeout <= 0)
+ /* Negative timeouts and 0's don't count, because we never
+ * want our timeout to drop to 0 or below, and because 0 could
+ * mean an error
+ */
return 0;
spin_lock(&at->at_lock);
if (unlikely(at->at_binstart == 0)) {
/* Special case to remove default from history */
- at->at_current = val;
- at->at_worst_ever = val;
- at->at_worst_time = now;
- at->at_hist[0] = val;
+ at->at_current_timeout = timeout;
+ at->at_worst_timeout_ever = timeout;
+ at->at_worst_timestamp = now;
+ at->at_hist[0] = timeout;
at->at_binstart = now;
} else if (now - at->at_binstart < binlimit ) {
/* in bin 0 */
- at->at_hist[0] = max(val, at->at_hist[0]);
- at->at_current = max(val, at->at_current);
+ at->at_hist[0] = max_t(timeout_t, timeout, at->at_hist[0]);
+ at->at_current_timeout = max_t(timeout_t, timeout,
+ at->at_current_timeout);
} else {
int i, shift;
- unsigned int maxv = val;
+ timeout_t maxv = timeout;
/* move bins over */
shift = (u32)(now - at->at_binstart) / binlimit;
for(i = AT_BINS - 1; i >= 0; i--) {
if (i >= shift) {
at->at_hist[i] = at->at_hist[i - shift];
- maxv = max(maxv, at->at_hist[i]);
+ maxv = max_t(timeout_t, maxv, at->at_hist[i]);
} else {
at->at_hist[i] = 0;
}
}
- at->at_hist[0] = val;
- at->at_current = maxv;
+ at->at_hist[0] = timeout;
+ at->at_current_timeout = maxv;
at->at_binstart += shift * binlimit;
}
- if (at->at_current > at->at_worst_ever) {
- at->at_worst_ever = at->at_current;
- at->at_worst_time = now;
- }
+ if (at->at_current_timeout > at->at_worst_timeout_ever) {
+ at->at_worst_timeout_ever = at->at_current_timeout;
+ at->at_worst_timestamp = now;
+ }
- if (at->at_flags & AT_FLG_NOHIST)
+ if (at->at_flags & AT_FLG_NOHIST)
/* Only keep last reported val; keeping the rest of the history
- for proc only */
- at->at_current = val;
+ * for debugfs only
+ */
+ at->at_current_timeout = timeout;
if (at_max > 0)
- at->at_current = min(at->at_current, at_max);
- at->at_current = max(at->at_current, at_min);
-
- if (at->at_current != old)
- CDEBUG(D_OTHER, "AT %p change: old=%u new=%u delta=%d "
- "(val=%u) hist %u %u %u %u\n", at,
- old, at->at_current, at->at_current - old, val,
+ at->at_current_timeout = min_t(timeout_t,
+ at->at_current_timeout, at_max);
+ at->at_current_timeout = max_t(timeout_t, at->at_current_timeout,
+ at_min);
+ if (at->at_current_timeout != old_timeout)
+ CDEBUG(D_OTHER,
+ "AT %p change: old=%u new=%u delta=%d (val=%d) hist %u %u %u %u\n",
+ at, old_timeout, at->at_current_timeout,
+ at->at_current_timeout - old_timeout, timeout,
at->at_hist[0], at->at_hist[1], at->at_hist[2],
at->at_hist[3]);
- /* if we changed, report the old value */
- old = (at->at_current != old) ? old : 0;
+ /* if we changed, report the old timeout value */
+ old_timeout = (at->at_current_timeout != old_timeout) ? old_timeout : 0;
spin_unlock(&at->at_lock);
- return old;
+ return old_timeout;
}
/* Find the imp_at index for a given portal; assign if space available */
/* See also lprocfs_rd_timeouts */
static int ptlrpc_lprocfs_timeouts_seq_show(struct seq_file *m, void *n)
{
- struct ptlrpc_service *svc = m->private;
- struct ptlrpc_service_part *svcpt;
- time64_t worstt;
- unsigned int cur;
- unsigned int worst;
- int i;
+ struct ptlrpc_service *svc = m->private;
+ struct ptlrpc_service_part *svcpt;
+ time64_t worst_timestamp;
+ timeout_t cur_timeout;
+ timeout_t worst_timeout;
+ int i;
if (AT_OFF) {
seq_printf(m, "adaptive timeouts off, using obd_timeout %u\n",
}
ptlrpc_service_for_each_part(svcpt, i, svc) {
- cur = at_get(&svcpt->scp_at_estimate);
- worst = svcpt->scp_at_estimate.at_worst_ever;
- worstt = svcpt->scp_at_estimate.at_worst_time;
+ cur_timeout = at_get(&svcpt->scp_at_estimate);
+ worst_timeout = svcpt->scp_at_estimate.at_worst_timeout_ever;
+ worst_timestamp = svcpt->scp_at_estimate.at_worst_timestamp;
seq_printf(m, "%10s : cur %3u worst %3u (at %lld, %llds ago) ",
- "service", cur, worst, (s64)worstt,
- (s64)(ktime_get_real_seconds() - worstt));
+ "service", cur_timeout, worst_timeout,
+ worst_timestamp,
+ ktime_get_real_seconds() - worst_timestamp);
lprocfs_at_hist_helper(m, &svcpt->scp_at_estimate);
}
(MSG_RESENT | MSG_REPLAY |
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_measured(&svcpt->scp_at_estimate,
- service_timeout);
+ * toward our service time estimate
+ */
+ timeout_t oldse = at_measured(&svcpt->scp_at_estimate,
+ service_timeout);
if (oldse != 0) {
DEBUG_REQ(D_ADAPTTO, req,
req->rq_export->exp_obd->obd_recovering)) {
lustre_msg_set_timeout(req->rq_repmsg, 0);
} else {
- time64_t timeout;
+ timeout_t timeout;
if (req->rq_export && req->rq_reqmsg != NULL &&
(flags & PTLRPC_REPLY_EARLY) &&
timeout = ktime_get_real_seconds() -
req->rq_arrival_time.tv_sec +
- min_t(time64_t, at_extra,
+ min_t(timeout_t, at_extra,
exp_obd->obd_recovery_timeout / 4);
} else {
timeout = at_get(&svcpt->scp_at_estimate);
struct ptlrpc_service_part *svcpt = req->rq_rqbd->rqbd_svcpt;
struct ptlrpc_request *reqcopy;
struct lustre_msg *reqmsg;
- time64_t olddl = req->rq_deadline - ktime_get_real_seconds();
+ timeout_t olddl = req->rq_deadline - ktime_get_real_seconds();
time64_t newdl;
int rc;
* difference between clients' and servers' expectations
*/
DEBUG_REQ(D_ADAPTTO, req,
- "%ssending early reply (deadline %+llds, margin %+llds) for %d+%d",
+ "%ssending early reply (deadline %+ds, margin %+ds) for %d+%d",
AT_OFF ? "AT off - not " : "",
- (s64)olddl, (s64)(olddl - at_get(&svcpt->scp_at_estimate)),
+ olddl, olddl - at_get(&svcpt->scp_at_estimate),
at_get(&svcpt->scp_at_estimate), at_extra);
if (AT_OFF)
if (olddl < 0) {
/* below message is checked in replay-ost-single.sh test_9 */
DEBUG_REQ(D_WARNING, req,
- "Already past deadline (%+llds), not sending early reply. Consider increasing at_early_margin (%d)?",
- (s64)olddl, at_early_margin);
+ "Already past deadline (%+ds), not sending early reply. Consider increasing at_early_margin (%d)?",
+ olddl, at_early_margin);
/* Return an error so we're not re-added to the timed list. */
RETURN(-ETIMEDOUT);
*/
if (req->rq_deadline >= newdl) {
DEBUG_REQ(D_WARNING, req,
- "Could not add any time (%lld/%lld), not sending early reply",
- (s64)olddl, (s64)(newdl - ktime_get_real_seconds()));
+ "Could not add any time (%d/%lld), not sending early reply",
+ olddl, newdl - ktime_get_real_seconds());
RETURN(-ETIMEDOUT);
}
__u32 index, count;
time64_t deadline;
time64_t now = ktime_get_real_seconds();
- s64 delay;
+ s64 delay_ms;
int first, counter = 0;
ENTRY;
spin_unlock(&svcpt->scp_at_lock);
RETURN(0);
}
- delay = ktime_ms_delta(ktime_get(), svcpt->scp_at_checktime);
+ delay_ms = ktime_ms_delta(ktime_get(), svcpt->scp_at_checktime);
svcpt->scp_at_check = 0;
if (array->paa_count == 0) {
*/
LCONSOLE_WARN("%s: This server is not able to keep up with request traffic (cpu-bound).\n",
svcpt->scp_service->srv_name);
- CWARN("earlyQ=%d reqQ=%d recA=%d, svcEst=%d, delay=%lld\n",
+ CWARN("earlyQ=%d reqQ=%d recA=%d, svcEst=%d, delay=%lldms\n",
counter, svcpt->scp_nreqs_incoming,
svcpt->scp_nreqs_active,
- at_get(&svcpt->scp_at_estimate), delay);
+ at_get(&svcpt->scp_at_estimate), delay_ms);
}
/*
/* req_in handling should/must be fast */
if (ktime_get_real_seconds() - req->rq_arrival_time.tv_sec > 5)
DEBUG_REQ(D_WARNING, req, "Slow req_in handling %llds",
- (s64)(ktime_get_real_seconds() -
- req->rq_arrival_time.tv_sec));
+ ktime_get_real_seconds() -
+ req->rq_arrival_time.tv_sec);
/* Set rpc server deadline and add it to the timed list */
deadline = (lustre_msghdr_get_flags(req->rq_reqmsg) &
}
}
-static void ptlrpc_watchdog_init(struct delayed_work *work, time_t time)
+static void ptlrpc_watchdog_init(struct delayed_work *work, timeout_t timeout)
{
INIT_DELAYED_WORK(work, ptlrpc_watchdog_fire);
- schedule_delayed_work(work, cfs_time_seconds(time));
+ schedule_delayed_work(work, cfs_time_seconds(timeout));
}
static void ptlrpc_watchdog_disable(struct delayed_work *work)
cancel_delayed_work_sync(work);
}
-static void ptlrpc_watchdog_touch(struct delayed_work *work, time_t time)
+static void ptlrpc_watchdog_touch(struct delayed_work *work, timeout_t timeout)
{
struct ptlrpc_thread *thread = container_of(&work->work,
struct ptlrpc_thread,
t_watchdog.work);
thread->t_touched = ktime_get();
- mod_delayed_work(system_wq, work, cfs_time_seconds(time));
+ mod_delayed_work(system_wq, work, cfs_time_seconds(timeout));
}
/**
if (ldlm_is_ast_sent(lock)) {
struct ptlrpc_service_part *svc;
- time64_t timeout;
+ timeout_t timeout;
svc = req->rq_rqbd->rqbd_svcpt;
timeout = at_est2timeout(at_get(&svc->scp_at_estimate));