Whamcloud - gitweb
LU-12769 recovery: use monotonic timer 74/36274/12
authorAlex Zhuravlev <bzzz@whamcloud.com>
Mon, 23 Sep 2019 08:26:19 +0000 (11:26 +0300)
committerOleg Drokin <green@whamcloud.com>
Wed, 9 Oct 2019 22:35:29 +0000 (22:35 +0000)
instead of real one. also use absolute values for timer.

One of the reasons for the move from jiffies based timer
to a hrtimer timer was to avoid the issue of time drift.
It was discovered due to test failures with recovery on
VMs that the high resolution wall clock can drift as well.
Moving to the monotonic clock for the hrtimer avoids this
drift completely and it is safe to use since the recovery
timestamp is not shared between nodes.

Signed-off-by: Alex Zhuravlev <bzzz@whamcloud.com>
Change-Id: I8b75121934c229dec8df7be0a4e69c1cda940d3f
Reviewed-on: https://review.whamcloud.com/36274
Tested-by: jenkins <devops@whamcloud.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/ldlm/ldlm_lib.c

index 50ce61c..0d95dd6 100644 (file)
@@ -1280,7 +1280,7 @@ no_export:
        CDEBUG(D_HA, "%s: connection from %s@%s %st%llu exp %p cur %lld last %lld\n",
               target->obd_name, cluuid.uuid, libcfs_nid2str(req->rq_peer.nid),
               target->obd_recovering ? "recovering/" : "", data->ocd_transno,
-              export, ktime_get_real_seconds(),
+              export, ktime_get_seconds(),
               export ? export->exp_last_request_time : 0);
 
        /*
@@ -1637,7 +1637,7 @@ static void target_finish_recovery(struct lu_target *lut)
 
        /* Only log a recovery message when recovery has occurred. */
        if (obd->obd_recovery_start) {
-               time64_t now = ktime_get_real_seconds();
+               time64_t now = ktime_get_seconds();
                time64_t elapsed_time;
 
                elapsed_time = max_t(time64_t, now - obd->obd_recovery_start,
@@ -1668,7 +1668,7 @@ static void target_finish_recovery(struct lu_target *lut)
        }
        spin_unlock(&obd->obd_recovery_task_lock);
 
-       obd->obd_recovery_end = ktime_get_real_seconds();
+       obd->obd_recovery_end = ktime_get_seconds();
 
        /* When recovery finished, cleanup orphans on MDS and OST. */
        if (obd->obd_type && OBP(obd, postrecov)) {
@@ -1798,9 +1798,10 @@ static void target_start_recovery_timer(struct obd_device *obd)
                return;
        }
 
-       delay = ktime_set(obd->obd_recovery_timeout, 0);
-       hrtimer_start(&obd->obd_recovery_timer, delay, HRTIMER_MODE_REL);
-       obd->obd_recovery_start = ktime_get_real_seconds();
+       obd->obd_recovery_start = ktime_get_seconds();
+       delay = ktime_set(obd->obd_recovery_start +
+                         obd->obd_recovery_timeout, 0);
+       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",
@@ -1859,14 +1860,14 @@ static void extend_recovery_timer(struct obd_device *obd, time_t dr_timeout,
                      obd->obd_name, timeout, extend);
 
        if (obd->obd_recovery_timeout < timeout) {
-               ktime_t now = ktime_get_real();
-               ktime_t end;
+               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_forward_now(&obd->obd_recovery_timer, left_ns);
-               left = ktime_divns(left_ns, NSEC_PER_MSEC);
+               hrtimer_start(&obd->obd_recovery_timer, end, HRTIMER_MODE_ABS);
+               left = ktime_divns(left_ns, NSEC_PER_SEC);
        }
        spin_unlock(&obd->obd_dev_lock);
 
@@ -2092,7 +2093,7 @@ repeat:
                        last = now;
                }
        }
-       if (obd->obd_recovery_start != 0 && ktime_get_real_seconds() >=
+       if (obd->obd_recovery_start != 0 && ktime_get_seconds() >=
              (obd->obd_recovery_start + obd->obd_recovery_time_hard)) {
                __u64 next_update_transno = 0;
 
@@ -2177,6 +2178,7 @@ repeat:
                return 1;
        } else if (obd->obd_recovery_expired) {
                obd->obd_recovery_expired = 0;
+
                /** If some clients died being recovered, evict them */
                LCONSOLE_WARN("%s: recovery is timed out, evict stale exports\n",
                              obd->obd_name);
@@ -2787,8 +2789,8 @@ void target_recovery_init(struct lu_target *lut, svc_handler_t handler)
        obd->obd_recovery_start = 0;
        obd->obd_recovery_end = 0;
 
-       hrtimer_init(&obd->obd_recovery_timer, CLOCK_REALTIME,
-                    HRTIMER_MODE_REL);
+       hrtimer_init(&obd->obd_recovery_timer, CLOCK_MONOTONIC,
+                    HRTIMER_MODE_ABS);
        obd->obd_recovery_timer.function = &target_recovery_expired;
        target_start_recovery_thread(lut, handler);
 }
@@ -3319,7 +3321,7 @@ static inline const char *bulk2type(struct ptlrpc_request *req)
 int target_bulk_io(struct obd_export *exp, struct ptlrpc_bulk_desc *desc)
 {
        struct ptlrpc_request *req = desc->bd_req;
-       time64_t start = ktime_get_real_seconds();
+       time64_t start = ktime_get_seconds();
        time64_t deadline;
        struct l_wait_info lwi;
        int rc = 0;
@@ -3368,7 +3370,7 @@ int target_bulk_io(struct obd_export *exp, struct ptlrpc_bulk_desc *desc)
                deadline = req->rq_deadline;
 
        do {
-               time64_t timeoutl = deadline - ktime_get_real_seconds();
+               time64_t timeoutl = deadline - ktime_get_seconds();
                long timeout_jiffies = timeoutl <= 0 ?
                                       1 : cfs_time_seconds(timeoutl);
                time64_t rq_deadline;
@@ -3389,7 +3391,7 @@ int target_bulk_io(struct obd_export *exp, struct ptlrpc_bulk_desc *desc)
                if (deadline > rq_deadline)
                        deadline = rq_deadline;
        } while (rc == -ETIMEDOUT &&
-                deadline > ktime_get_real_seconds());
+                deadline > ktime_get_seconds());
 
        if (rc == -ETIMEDOUT) {
                DEBUG_REQ(D_ERROR, req, "timeout on bulk %s after %lld%+llds",