Whamcloud - gitweb
LU-8541 ldlm: don't use jiffies as sysfs parameter 70/28370/10
authorJames Simmons <uja.ornl@yahoo.com>
Thu, 31 Aug 2017 20:17:42 +0000 (16:17 -0400)
committerOleg Drokin <oleg.drokin@intel.com>
Thu, 21 Sep 2017 06:13:46 +0000 (06:13 +0000)
The ldlm sysfs file handles lru_max_age in jiffies which is wrong
since jiffies are not consistent across machine since HZ is
configurable at compile time. Talking to most users they thought
lru_max_age was in seconds which is incorrect. The best way to
fix this is to move lru_max_age to millisecs since most systems
lustre deals with sets HZ to 1000. To make it clear it is in
milliseconds print out lru_max_age with "ms". Since users tend
to think in seconds allow passing in seconds besides milliseconds
and internally converting them to nanaseconds. Since we have to
support milliseconds move to ktime_t since we can't use time64_t.
Unfortunately, this makes a relatively large patch, but I could
not find a way to split it up some more without breaking atomicity
of the change.

Change-Id: I0b1814fd9d903767f62fe141d2c95845b75fb95a
Signed-off-by: James Simmons <uja.ornl@yahoo.com>
Reviewed-on: https://review.whamcloud.com/28370
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Dmitry Eremin <dmitry.eremin@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
libcfs/autoconf/lustre-libcfs.m4
libcfs/include/libcfs/linux/linux-time.h
lustre/include/lustre_dlm.h
lustre/ldlm/ldlm_internal.h
lustre/ldlm/ldlm_lock.c
lustre/ldlm/ldlm_lockd.c
lustre/ldlm/ldlm_reclaim.c
lustre/ldlm/ldlm_request.c
lustre/ldlm/ldlm_resource.c
lustre/ofd/ofd_dev.c
lustre/tests/sanity.sh

index f61f728..f9447df 100644 (file)
@@ -367,6 +367,25 @@ ktime_after, [
 ]) # LIBCFS_KTIME_AFTER
 
 #
+# Kernel version 3.12 introduced ktime_before
+# See linux commit 67cb9366ff5f99868100198efba5ca88aaa6ad25
+#
+AC_DEFUN([LIBCFS_KTIME_BEFORE],[
+LB_CHECK_COMPILE([does function 'ktime_before' exist],
+ktime_before, [
+       #include <linux/ktime.h>
+],[
+       ktime_t start = ktime_set(0, 0);
+       ktime_t end = start;
+
+       ktime_before(start, end);
+],[
+       AC_DEFINE(HAVE_KTIME_BEFORE, 1,
+               [ktime_before is available])
+])
+]) # LIBCFS_KTIME_BEFORE
+
+#
 # FC19 3.12 kernel struct shrinker change
 #
 AC_DEFUN([LIBCFS_SHRINKER_COUNT],[
@@ -766,6 +785,7 @@ LIBCFS_KTIME_GET_TS64
 LIBCFS_KERNEL_PARAM_OPS
 LIBCFS_KTIME_ADD
 LIBCFS_KTIME_AFTER
+LIBCFS_KTIME_BEFORE
 LIBCFS_SHRINKER_COUNT
 # 3.17
 LIBCFS_HLIST_ADD_AFTER
index a217929..6a391e2 100644 (file)
@@ -154,6 +154,13 @@ static inline bool ktime_after(const ktime_t cmp1, const ktime_t cmp2)
 }
 #endif /* !HAVE_KTIME_AFTER */
 
+#ifndef HAVE_KTIME_BEFORE
+static inline bool ktime_before(const ktime_t cmp1, const ktime_t cmp2)
+{
+       return cmp1.tv64 < cmp2.tv64;
+}
+#endif /* !HAVE_KTIME_BEFORE */
+
 #ifndef HAVE_KTIME_GET_TS64
 void ktime_get_ts64(struct timespec64 *ts);
 #endif /* HAVE_KTIME_GET_TS */
index 62382da..17b51ae 100644 (file)
@@ -62,7 +62,7 @@ extern struct kset *ldlm_svc_kset;
 #define OBD_LDLM_DEVICENAME  "ldlm"
 
 #define LDLM_DEFAULT_LRU_SIZE (100 * num_online_cpus())
-#define LDLM_DEFAULT_MAX_ALIVE (cfs_time_seconds(3900)) /* 65 min */
+#define LDLM_DEFAULT_MAX_ALIVE         3900    /* 3900 seconds ~65 min */
 #define LDLM_CTIME_AGE_LIMIT (10)
 #define LDLM_DEFAULT_PARALLEL_AST_LIMIT 1024
 
@@ -423,8 +423,10 @@ struct ldlm_namespace {
         * controlled by available memory on this client and on server.
         */
        unsigned int            ns_max_unused;
+
        /** Maximum allowed age (last used time) for locks in the LRU */
-       unsigned int            ns_max_age;
+       ktime_t                 ns_max_age;
+
        /**
         * Server only: number of times we evicted clients due to lack of reply
         * to ASTs.
@@ -819,10 +821,9 @@ struct ldlm_lock {
        time64_t                l_last_activity;
 
        /**
-        * Time last used by e.g. being matched by lock match.
-        * Jiffies. Should be converted to time if needed.
+        * Time, in nanoseconds, last used by e.g. being matched by lock match.
         */
-       cfs_time_t              l_last_used;
+       ktime_t                 l_last_used;
 
        /** Originally requested extent for the extent lock. */
        struct ldlm_extent      l_req_extent;
index 0ee5520..8ef4709 100644 (file)
@@ -162,9 +162,9 @@ void ldlm_discard_bl_list(struct list_head *bl_list);
 int ldlm_run_ast_work(struct ldlm_namespace *ns, struct list_head *rpc_list,
                       ldlm_desc_ast_t ast_type);
 int ldlm_work_gl_ast_lock(struct ptlrpc_request_set *rqset, void *opaq);
-int ldlm_lock_remove_from_lru_check(struct ldlm_lock *lock,
-                                   cfs_time_t last_use);
-#define ldlm_lock_remove_from_lru(lock) ldlm_lock_remove_from_lru_check(lock, 0)
+int ldlm_lock_remove_from_lru_check(struct ldlm_lock *lock, ktime_t last_use);
+#define ldlm_lock_remove_from_lru(lock) \
+               ldlm_lock_remove_from_lru_check(lock, ktime_set(0, 0))
 int ldlm_lock_remove_from_lru_nolock(struct ldlm_lock *lock);
 void ldlm_lock_add_to_lru_nolock(struct ldlm_lock *lock);
 void ldlm_lock_add_to_lru(struct ldlm_lock *lock);
index a480054..8d427ec 100644 (file)
@@ -255,7 +255,7 @@ int ldlm_lock_remove_from_lru_nolock(struct ldlm_lock *lock)
  *           otherwise, the lock hasn't been in the LRU list.
  * \retval 1 the lock was in LRU list and removed.
  */
-int ldlm_lock_remove_from_lru_check(struct ldlm_lock *lock, cfs_time_t last_use)
+int ldlm_lock_remove_from_lru_check(struct ldlm_lock *lock, ktime_t last_use)
 {
        struct ldlm_namespace *ns = ldlm_lock_to_ns(lock);
        int rc = 0;
@@ -267,7 +267,8 @@ int ldlm_lock_remove_from_lru_check(struct ldlm_lock *lock, cfs_time_t last_use)
        }
 
        spin_lock(&ns->ns_lock);
-       if (last_use == 0 || last_use == lock->l_last_used)
+       if (!ktime_compare(last_use, ktime_set(0, 0)) ||
+           !ktime_compare(last_use, lock->l_last_used))
                rc = ldlm_lock_remove_from_lru_nolock(lock);
        spin_unlock(&ns->ns_lock);
 
@@ -281,7 +282,7 @@ void ldlm_lock_add_to_lru_nolock(struct ldlm_lock *lock)
 {
        struct ldlm_namespace *ns = ldlm_lock_to_ns(lock);
 
-       lock->l_last_used = cfs_time_current();
+       lock->l_last_used = ktime_get();
        LASSERT(list_empty(&lock->l_lru));
        LASSERT(lock->l_resource->lr_type != LDLM_FLOCK);
        list_add_tail(&lock->l_lru, &ns->ns_unused_list);
index 2209253..3e80cb2 100644 (file)
@@ -1946,9 +1946,9 @@ static void ldlm_handle_gl_callback(struct ptlrpc_request *req,
         lock_res_and_lock(lock);
         if (lock->l_granted_mode == LCK_PW &&
             !lock->l_readers && !lock->l_writers &&
-            cfs_time_after(cfs_time_current(),
-                           cfs_time_add(lock->l_last_used,
-                                        cfs_time_seconds(10)))) {
+           ktime_after(ktime_get(),
+                       ktime_add(lock->l_last_used,
+                                 ktime_set(10, 0)))) {
                 unlock_res_and_lock(lock);
                 if (ldlm_bl_to_thread_lock(ns, NULL, lock))
                         ldlm_handle_bl_callback(ns, NULL, lock);
index b551ea2..cf4c87f 100644 (file)
@@ -63,8 +63,8 @@ __u64 ldlm_lock_limit_mb;
 
 struct percpu_counter          ldlm_granted_total;
 static atomic_t                        ldlm_nr_reclaimer;
-static cfs_duration_t          ldlm_last_reclaim_age;
-static cfs_time_t              ldlm_last_reclaim_time;
+static s64                     ldlm_last_reclaim_age_ns;
+static ktime_t                 ldlm_last_reclaim_time;
 
 struct ldlm_reclaim_cb_data {
        struct list_head         rcd_rpc_list;
@@ -73,7 +73,7 @@ struct ldlm_reclaim_cb_data {
        int                      rcd_cursor;
        int                      rcd_start;
        bool                     rcd_skip;
-       cfs_duration_t           rcd_age;
+       s64                      rcd_age_ns;
        struct cfs_hash_bd      *rcd_prev_bd;
 };
 
@@ -143,9 +143,9 @@ static int ldlm_reclaim_lock_cb(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                        continue;
 
                if (!OBD_FAIL_CHECK(OBD_FAIL_LDLM_WATERMARK_LOW) &&
-                   cfs_time_before(cfs_time_current(),
-                                   cfs_time_add(lock->l_last_used,
-                                                data->rcd_age)))
+                   ktime_before(ktime_get(),
+                                ktime_add_ns(lock->l_last_used,
+                                             data->rcd_age_ns)))
                        continue;
 
                if (!ldlm_is_ast_sent(lock)) {
@@ -177,7 +177,7 @@ static int ldlm_reclaim_lock_cb(struct cfs_hash *hs, struct cfs_hash_bd *bd,
  * \param[out] count   count of lock still to be revoked
  */
 static void ldlm_reclaim_res(struct ldlm_namespace *ns, int *count,
-                            cfs_duration_t age, bool skip)
+                            s64 age_ns, bool skip)
 {
        struct ldlm_reclaim_cb_data     data;
        int                             idx, type, start;
@@ -201,7 +201,7 @@ static void ldlm_reclaim_res(struct ldlm_namespace *ns, int *count,
        INIT_LIST_HEAD(&data.rcd_rpc_list);
        data.rcd_added = 0;
        data.rcd_total = *count;
-       data.rcd_age = age;
+       data.rcd_age_ns = age_ns;
        data.rcd_skip = skip;
        data.rcd_prev_bd = NULL;
        start = ns->ns_reclaim_start % CFS_HASH_NBKT(ns->ns_rs_hash);
@@ -222,20 +222,22 @@ static void ldlm_reclaim_res(struct ldlm_namespace *ns, int *count,
 }
 
 #define LDLM_RECLAIM_BATCH     512
-#define LDLM_RECLAIM_AGE_MIN   cfs_time_seconds(300)
-#define LDLM_RECLAIM_AGE_MAX   (LDLM_DEFAULT_MAX_ALIVE * 3 / 4)
+#define LDLM_RECLAIM_AGE_MIN   (300 * NSEC_PER_SEC)
+#define LDLM_RECLAIM_AGE_MAX   (LDLM_DEFAULT_MAX_ALIVE * NSEC_PER_SEC * 3 / 4)
 
-static inline cfs_duration_t ldlm_reclaim_age(void)
+static inline s64 ldlm_reclaim_age(void)
 {
-       cfs_duration_t  age;
-
-       age = ldlm_last_reclaim_age +
-               cfs_time_sub(cfs_time_current(), ldlm_last_reclaim_time);
-       if (age > LDLM_RECLAIM_AGE_MAX)
-               age = LDLM_RECLAIM_AGE_MAX;
-       else if (age < (LDLM_RECLAIM_AGE_MIN * 2))
-               age = LDLM_RECLAIM_AGE_MIN;
-       return age;
+       s64 age_ns = ldlm_last_reclaim_age_ns;
+       ktime_t now = ktime_get();
+       ktime_t diff;
+
+       diff = ktime_sub(now, ldlm_last_reclaim_time);
+       age_ns += ktime_to_ns(diff);
+       if (age_ns > LDLM_RECLAIM_AGE_MAX)
+               age_ns = LDLM_RECLAIM_AGE_MAX;
+       else if (age_ns < (LDLM_RECLAIM_AGE_MIN * 2))
+               age_ns = LDLM_RECLAIM_AGE_MIN;
+       return age_ns;
 }
 
 /**
@@ -249,7 +251,7 @@ static void ldlm_reclaim_ns(void)
        int                      count = LDLM_RECLAIM_BATCH;
        int                      ns_nr, nr_processed;
        enum ldlm_side           ns_cli = LDLM_NAMESPACE_SERVER;
-       cfs_duration_t           age;
+       s64 age_ns;
        bool                     skip = true;
        ENTRY;
 
@@ -258,7 +260,7 @@ static void ldlm_reclaim_ns(void)
                return;
        }
 
-       age = ldlm_reclaim_age();
+       age_ns = ldlm_reclaim_age();
 again:
        nr_processed = 0;
        ns_nr = ldlm_namespace_nr_read(ns_cli);
@@ -274,21 +276,21 @@ again:
                ldlm_namespace_move_to_active_locked(ns, ns_cli);
                mutex_unlock(ldlm_namespace_lock(ns_cli));
 
-               ldlm_reclaim_res(ns, &count, age, skip);
+               ldlm_reclaim_res(ns, &count, age_ns, skip);
                ldlm_namespace_put(ns);
                nr_processed++;
        }
 
-       if (count > 0 && age > LDLM_RECLAIM_AGE_MIN) {
-               age >>= 1;
-               if (age < (LDLM_RECLAIM_AGE_MIN * 2))
-                       age = LDLM_RECLAIM_AGE_MIN;
+       if (count > 0 && age_ns > LDLM_RECLAIM_AGE_MIN) {
+               age_ns >>= 1;
+               if (age_ns < (LDLM_RECLAIM_AGE_MIN * 2))
+                       age_ns = LDLM_RECLAIM_AGE_MIN;
                skip = false;
                goto again;
        }
 
-       ldlm_last_reclaim_age = age;
-       ldlm_last_reclaim_time = cfs_time_current();
+       ldlm_last_reclaim_age_ns = age_ns;
+       ldlm_last_reclaim_time = ktime_get();
 out:
        atomic_add_unless(&ldlm_nr_reclaimer, -1, 0);
        EXIT;
@@ -299,7 +301,7 @@ void ldlm_reclaim_add(struct ldlm_lock *lock)
        if (!ldlm_lock_reclaimable(lock))
                return;
        percpu_counter_add(&ldlm_granted_total, 1);
-       lock->l_last_used = cfs_time_current();
+       lock->l_last_used = ktime_get();
 }
 
 void ldlm_reclaim_del(struct ldlm_lock *lock)
@@ -367,8 +369,8 @@ int ldlm_reclaim_setup(void)
        ldlm_lock_limit = ldlm_ratio2locknr(LDLM_WM_RATIO_HIGH_DEFAULT);
        ldlm_lock_limit_mb = ldlm_locknr2mb(ldlm_lock_limit);
 
-       ldlm_last_reclaim_age = LDLM_RECLAIM_AGE_MAX;
-       ldlm_last_reclaim_time = cfs_time_current();
+       ldlm_last_reclaim_age_ns = LDLM_RECLAIM_AGE_MAX;
+       ldlm_last_reclaim_time = ktime_get();
 
 #ifdef HAVE_PERCPU_COUNTER_INIT_GFP_FLAG
        return percpu_counter_init(&ldlm_granted_total, 0, GFP_KERNEL);
index 37c2db0..fb67a1e 100644 (file)
@@ -1502,10 +1502,10 @@ static enum ldlm_policy_res ldlm_cancel_lrur_policy(struct ldlm_namespace *ns,
                                                    int unused, int added,
                                                    int count)
 {
-       cfs_time_t cur = cfs_time_current();
+       ktime_t cur = ktime_get();
        struct ldlm_pool *pl = &ns->ns_pool;
-       __u64 slv, lvf, lv;
-       cfs_time_t la;
+       u64 slv, lvf, lv;
+       s64 la;
 
        /* Stop LRU processing when we reach past @count or have checked all
         * locks in LRU. */
@@ -1513,15 +1513,15 @@ static enum ldlm_policy_res ldlm_cancel_lrur_policy(struct ldlm_namespace *ns,
                return LDLM_POLICY_KEEP_LOCK;
 
        /* Despite of the LV, It doesn't make sense to keep the lock which
-        * is unused for ns_max_age time. */
-       if (cfs_time_after(cfs_time_current(),
-                          cfs_time_add(lock->l_last_used, ns->ns_max_age)))
+        * is unused for ns_max_age time.
+        */
+       if (ktime_after(ktime_get(),
+                       ktime_add(lock->l_last_used, ns->ns_max_age)))
                return LDLM_POLICY_CANCEL_LOCK;
 
        slv = ldlm_pool_get_slv(pl);
        lvf = ldlm_pool_get_lvf(pl);
-       la = cfs_duration_sec(cfs_time_sub(cur,
-                             lock->l_last_used));
+       la = ktime_to_ns(ktime_sub(cur, lock->l_last_used)) / NSEC_PER_SEC;
        lv = lvf * la * unused;
 
        /* Inform pool about current CLV to see it via proc. */
@@ -1585,8 +1585,8 @@ static enum ldlm_policy_res ldlm_cancel_aged_policy(struct ldlm_namespace *ns,
                                                    int count)
 {
        if ((added >= count) &&
-           cfs_time_before(cfs_time_current(),
-                           cfs_time_add(lock->l_last_used, ns->ns_max_age)))
+           ktime_before(ktime_get(),
+                        ktime_add(lock->l_last_used, ns->ns_max_age)))
                return LDLM_POLICY_KEEP_LOCK;
 
        return LDLM_POLICY_CANCEL_LOCK;
@@ -1719,7 +1719,7 @@ static int ldlm_prepare_lru_list(struct ldlm_namespace *ns,
 
        while (!list_empty(&ns->ns_unused_list)) {
                enum ldlm_policy_res result;
-               cfs_time_t last_use = 0;
+               ktime_t last_use = ktime_set(0, 0);
 
                /* all unused locks */
                if (remained-- <= 0)
@@ -1739,13 +1739,11 @@ static int ldlm_prepare_lru_list(struct ldlm_namespace *ns,
                                continue;
 
                        last_use = lock->l_last_used;
-                       if (last_use == cfs_time_current())
-                               continue;
 
                        /* Somebody is already doing CANCEL. No need for this
                         * lock in LRU, do not traverse it again. */
                        if (!ldlm_is_canceling(lock))
-                                break;
+                               break;
 
                        ldlm_lock_remove_from_lru_nolock(lock);
                }
index 5cb58f5..31ee704 100644 (file)
@@ -407,7 +407,7 @@ static ssize_t lru_max_age_show(struct kobject *kobj, struct attribute *attr,
        struct ldlm_namespace *ns = container_of(kobj, struct ldlm_namespace,
                                                 ns_kobj);
 
-       return sprintf(buf, "%u\n", ns->ns_max_age);
+       return sprintf(buf, "%lld\n", ktime_to_ms(ns->ns_max_age));
 }
 
 static ssize_t lru_max_age_store(struct kobject *kobj, struct attribute *attr,
@@ -415,14 +415,27 @@ static ssize_t lru_max_age_store(struct kobject *kobj, struct attribute *attr,
 {
        struct ldlm_namespace *ns = container_of(kobj, struct ldlm_namespace,
                                                 ns_kobj);
-       unsigned long tmp;
+       int scale = NSEC_PER_MSEC;
+       unsigned long long tmp;
+       char *buf;
        int err;
 
-       err = kstrtoul(buffer, 10, &tmp);
+       /* Did the user ask in seconds or milliseconds. Default is in ms */
+       buf = strstr(buffer, "ms");
+       if (!buf) {
+               buf = strchr(buffer, 's');
+               if (buf)
+                       scale = NSEC_PER_SEC;
+       }
+
+       if (buf)
+               *buf = '\0';
+
+       err = kstrtoull(buffer, 10, &tmp);
        if (err != 0)
                return -EINVAL;
 
-       ns->ns_max_age = tmp;
+       ns->ns_max_age = ktime_set(0, tmp * scale);
 
        return count;
 }
@@ -940,7 +953,7 @@ struct ldlm_namespace *ldlm_namespace_new(struct obd_device *obd, char *name,
         ns->ns_max_parallel_ast   = LDLM_DEFAULT_PARALLEL_AST_LIMIT;
         ns->ns_nr_unused          = 0;
         ns->ns_max_unused         = LDLM_DEFAULT_LRU_SIZE;
-        ns->ns_max_age            = LDLM_DEFAULT_MAX_ALIVE;
+       ns->ns_max_age            = ktime_set(LDLM_DEFAULT_MAX_ALIVE, 0);
         ns->ns_ctime_age_limit    = LDLM_CTIME_AGE_LIMIT;
         ns->ns_timeouts           = 0;
         ns->ns_orig_connect_flags = 0;
index 17ce15f..3bb3d59 100644 (file)
@@ -2432,7 +2432,7 @@ static void ofd_prolong_extent_locks(struct tgt_session_info *tsi,
                                LDLM_LOCK_PUT(lock);
                                RETURN_EXIT;
                        }
-                       lock->l_last_used = cfs_time_current();
+                       lock->l_last_used = ktime_get();
                        LDLM_LOCK_PUT(lock);
                }
        }
index 43bf632..a136f4b 100755 (executable)
@@ -8972,7 +8972,7 @@ test_124c() {
        echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
 
        # set lru_max_age to 1 sec
-       $LCTL set_param $nsdir.lru_max_age=1000 # jiffies
+       $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
        echo "sleep $((recalc_p * 2)) seconds..."
        sleep $((recalc_p * 2))