]) # 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],[
LIBCFS_KERNEL_PARAM_OPS
LIBCFS_KTIME_ADD
LIBCFS_KTIME_AFTER
+LIBCFS_KTIME_BEFORE
LIBCFS_SHRINKER_COUNT
# 3.17
LIBCFS_HLIST_ADD_AFTER
}
#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 */
#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
* 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.
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;
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);
* 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;
}
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);
{
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);
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);
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;
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;
};
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)) {
* \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;
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);
}
#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;
}
/**
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;
return;
}
- age = ldlm_reclaim_age();
+ age_ns = ldlm_reclaim_age();
again:
nr_processed = 0;
ns_nr = ldlm_namespace_nr_read(ns_cli);
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;
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)
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);
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. */
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. */
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;
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)
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);
}
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,
{
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;
}
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;
LDLM_LOCK_PUT(lock);
RETURN_EXIT;
}
- lock->l_last_used = cfs_time_current();
+ lock->l_last_used = ktime_get();
LDLM_LOCK_PUT(lock);
}
}
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))