- now = ktime_get_real_seconds();
- to = obd->obd_recovery_timeout;
- end = obd->obd_recovery_start + to;
- left = end - now;
-
- if (extend && (drt > left)) {
- to += drt - left;
- } else if (!extend && (drt > to)) {
- to = drt;
- }
-
- if (to > obd->obd_recovery_time_hard) {
- to = obd->obd_recovery_time_hard;
- CWARN("%s: extended recovery timer reaching hard limit: %lld, extend: %d\n",
- obd->obd_name, to, extend);
- }
-
- if (obd->obd_recovery_timeout < to) {
- obd->obd_recovery_timeout = to;
- end = obd->obd_recovery_start + to;
- mod_timer(&obd->obd_recovery_timer,
- jiffies + cfs_time_seconds(end - now));
- }
+ left_ns = hrtimer_expires_remaining(&obd->obd_recovery_timer);
+ left = ktime_divns(left_ns, NSEC_PER_SEC);
+
+ if (extend) {
+ timeout = obd->obd_recovery_timeout;
+ /* dr_timeout will happen after the hrtimer has expired.
+ * Add the excess time to the soft recovery timeout without
+ * exceeding the hard recovery timeout.
+ */
+ if (dr_timeout > left) {
+ timeout += dr_timeout - left;
+ timeout = min_t(timeout_t, obd->obd_recovery_time_hard,
+ timeout);
+ }
+ } else {
+ 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: %d, extend: %d\n",
+ obd->obd_name, timeout, extend);
+
+ if (obd->obd_recovery_timeout < timeout) {
+ ktime_t end, now;
+
+ obd->obd_recovery_timeout = timeout;
+ end = ktime_set(obd->obd_recovery_start + timeout, 0);
+ now = ktime_set(ktime_get_seconds(), 0);
+ left_ns = ktime_sub(end, now);
+ hrtimer_start(&obd->obd_recovery_timer, end, HRTIMER_MODE_ABS);
+ left = ktime_divns(left_ns, NSEC_PER_SEC);
+ }