1 diff --git a/fs/lustre/ldlm/ldlm_pool.c b/fs/lustre/ldlm/ldlm_pool.c
2 index b6d64f0f26f8..8eb29c4147f7 100644
3 --- a/fs/lustre/ldlm/ldlm_pool.c
4 +++ b/fs/lustre/ldlm/ldlm_pool.c
5 @@ -286,13 +286,13 @@ static void ldlm_pool_recalc_slv(struct ldlm_pool *pl)
7 * \pre ->pl_lock is locked.
9 -static void ldlm_pool_recalc_stats(struct ldlm_pool *pl)
10 +static void ldlm_pool_recalc_stats(struct ldlm_pool *pl, timeout_t period)
12 int grant_plan = pl->pl_grant_plan;
13 __u64 slv = pl->pl_server_lock_volume;
14 int granted = ldlm_pool_granted(pl);
15 - int grant_rate = atomic_read(&pl->pl_grant_rate);
16 - int cancel_rate = atomic_read(&pl->pl_cancel_rate);
17 + int grant_rate = atomic_read(&pl->pl_grant_rate) / period;
18 + int cancel_rate = atomic_read(&pl->pl_cancel_rate) / period;
20 lprocfs_counter_add(pl->pl_stats, LDLM_POOL_SLV_STAT,
22 @@ -334,16 +334,16 @@ static void ldlm_srv_pool_push_slv(struct ldlm_pool *pl)
24 static int ldlm_srv_pool_recalc(struct ldlm_pool *pl)
26 - time64_t recalc_interval_sec;
27 + timeout_t recalc_interval_sec;
31 - recalc_interval_sec = ktime_get_real_seconds() - pl->pl_recalc_time;
32 + recalc_interval_sec = ktime_get_seconds() - pl->pl_recalc_time;
33 if (recalc_interval_sec < pl->pl_recalc_period)
36 spin_lock(&pl->pl_lock);
37 - recalc_interval_sec = ktime_get_real_seconds() - pl->pl_recalc_time;
38 + recalc_interval_sec = ktime_get_seconds() - pl->pl_recalc_time;
39 if (recalc_interval_sec < pl->pl_recalc_period) {
40 spin_unlock(&pl->pl_lock);
42 @@ -364,7 +364,7 @@ static int ldlm_srv_pool_recalc(struct ldlm_pool *pl)
44 ldlm_pool_recalc_grant_plan(pl);
46 - pl->pl_recalc_time = ktime_get_real_seconds();
47 + pl->pl_recalc_time = ktime_get_seconds();
48 lprocfs_counter_add(pl->pl_stats, LDLM_POOL_TIMING_STAT,
50 spin_unlock(&pl->pl_lock);
51 @@ -473,12 +473,12 @@ static void ldlm_cli_pool_pop_slv(struct ldlm_pool *pl)
53 static int ldlm_cli_pool_recalc(struct ldlm_pool *pl)
55 - time64_t recalc_interval_sec;
56 + timeout_t recalc_interval_sec;
61 - recalc_interval_sec = ktime_get_real_seconds() - pl->pl_recalc_time;
62 + recalc_interval_sec = ktime_get_seconds() - pl->pl_recalc_time;
63 if (recalc_interval_sec < pl->pl_recalc_period)
66 @@ -486,7 +486,7 @@ static int ldlm_cli_pool_recalc(struct ldlm_pool *pl)
68 * Check if we need to recalc lists now.
70 - recalc_interval_sec = ktime_get_real_seconds() - pl->pl_recalc_time;
71 + recalc_interval_sec = ktime_get_seconds() - pl->pl_recalc_time;
72 if (recalc_interval_sec < pl->pl_recalc_period) {
73 spin_unlock(&pl->pl_lock);
75 @@ -511,7 +511,7 @@ static int ldlm_cli_pool_recalc(struct ldlm_pool *pl)
76 * Time of LRU resizing might be longer than period,
77 * so update after LRU resizing rather than before it.
79 - pl->pl_recalc_time = ktime_get_real_seconds();
80 + pl->pl_recalc_time = ktime_get_seconds();
81 lprocfs_counter_add(pl->pl_stats, LDLM_POOL_TIMING_STAT,
83 spin_unlock(&pl->pl_lock);
84 @@ -540,7 +540,9 @@ static int ldlm_cli_pool_shrink(struct ldlm_pool *pl,
86 * Make sure that pool knows last SLV and Limit from obd.
88 + spin_lock(&pl->pl_lock);
89 ldlm_cli_pool_pop_slv(pl);
90 + spin_unlock(&pl->pl_lock);
92 spin_lock(&ns->ns_lock);
93 unused = ns->ns_nr_unused;
94 @@ -566,23 +568,24 @@ static struct ldlm_pool_ops ldlm_cli_pool_ops = {
96 * Pool recalc wrapper. Will call either client or server pool recalc callback
97 * depending what pool \a pl is used.
99 + * \retval time in seconds for the next recalc of this pool
101 time64_t ldlm_pool_recalc(struct ldlm_pool *pl)
103 - time64_t recalc_interval_sec;
104 + timeout_t recalc_interval_sec;
107 - recalc_interval_sec = ktime_get_real_seconds() - pl->pl_recalc_time;
108 + recalc_interval_sec = ktime_get_seconds() - pl->pl_recalc_time;
109 if (recalc_interval_sec > 0) {
110 spin_lock(&pl->pl_lock);
111 - recalc_interval_sec = ktime_get_real_seconds() -
112 - pl->pl_recalc_time;
113 + recalc_interval_sec = ktime_get_seconds() - pl->pl_recalc_time;
115 if (recalc_interval_sec > 0) {
117 - * Update pool statistics every 1s.
118 + * Update pool statistics every recalc interval.
120 - ldlm_pool_recalc_stats(pl);
121 + ldlm_pool_recalc_stats(pl, recalc_interval_sec);
124 * Zero out all rates and speed for the last period.
125 @@ -599,19 +602,7 @@ time64_t ldlm_pool_recalc(struct ldlm_pool *pl)
129 - recalc_interval_sec = pl->pl_recalc_time - ktime_get_real_seconds() +
130 - pl->pl_recalc_period;
131 - if (recalc_interval_sec <= 0) {
132 - /* DEBUG: should be re-removed after LU-4536 is fixed */
133 - CDEBUG(D_DLMTRACE, "%s: Negative interval(%lld), too short period(%lld)\n",
134 - pl->pl_name, recalc_interval_sec,
135 - (s64)pl->pl_recalc_period);
137 - /* Prevent too frequent recalculation. */
138 - recalc_interval_sec = 1;
141 - return recalc_interval_sec;
142 + return pl->pl_recalc_time + pl->pl_recalc_period;
146 @@ -657,6 +648,7 @@ static int lprocfs_pool_state_seq_show(struct seq_file *m, void *unused)
147 int granted, grant_rate, cancel_rate, grant_step;
148 int grant_speed, grant_plan, lvf;
149 struct ldlm_pool *pl = m->private;
154 @@ -666,8 +658,11 @@ static int lprocfs_pool_state_seq_show(struct seq_file *m, void *unused)
155 limit = ldlm_pool_get_limit(pl);
156 grant_plan = pl->pl_grant_plan;
157 granted = ldlm_pool_granted(pl);
158 - grant_rate = atomic_read(&pl->pl_grant_rate);
159 - cancel_rate = atomic_read(&pl->pl_cancel_rate);
160 + period = ktime_get_seconds() - pl->pl_recalc_time;
163 + grant_rate = atomic_read(&pl->pl_grant_rate) / period;
164 + cancel_rate = atomic_read(&pl->pl_cancel_rate) / period;
165 grant_speed = grant_rate - cancel_rate;
166 lvf = atomic_read(&pl->pl_lock_volume_factor);
167 grant_step = ldlm_pool_t2gsp(pl->pl_recalc_period);
168 @@ -677,7 +672,7 @@ static int lprocfs_pool_state_seq_show(struct seq_file *m, void *unused)
172 - pl->pl_name, slv, clv, lvf);
173 + pl->pl_name, slv, clv, (lvf * 100) >> 8);
175 if (ns_is_server(ldlm_pl2ns(pl))) {
176 seq_printf(m, " GSP: %d%%\n", grant_step);
177 @@ -698,11 +693,15 @@ static ssize_t grant_speed_show(struct kobject *kobj, struct attribute *attr,
178 struct ldlm_pool *pl = container_of(kobj, struct ldlm_pool,
183 spin_lock(&pl->pl_lock);
184 /* serialize with ldlm_pool_recalc */
185 - grant_speed = atomic_read(&pl->pl_grant_rate) -
186 - atomic_read(&pl->pl_cancel_rate);
187 + period = ktime_get_seconds() - pl->pl_recalc_time;
190 + grant_speed = (atomic_read(&pl->pl_grant_rate) -
191 + atomic_read(&pl->pl_cancel_rate)) / period;
192 spin_unlock(&pl->pl_lock);
193 return sprintf(buf, "%d\n", grant_speed);
195 @@ -718,6 +717,9 @@ LUSTRE_RW_ATTR(recalc_period);
196 LDLM_POOL_SYSFS_READER_NOLOCK_SHOW(server_lock_volume, u64);
197 LUSTRE_RO_ATTR(server_lock_volume);
199 +LDLM_POOL_SYSFS_READER_NOLOCK_SHOW(client_lock_volume, u64);
200 +LUSTRE_RO_ATTR(client_lock_volume);
202 LDLM_POOL_SYSFS_READER_NOLOCK_SHOW(limit, atomic);
203 LDLM_POOL_SYSFS_WRITER_NOLOCK_STORE(limit, atomic);
204 LUSTRE_RW_ATTR(limit);
205 @@ -731,16 +733,58 @@ LUSTRE_RO_ATTR(cancel_rate);
206 LDLM_POOL_SYSFS_READER_NOLOCK_SHOW(grant_rate, atomic);
207 LUSTRE_RO_ATTR(grant_rate);
209 -LDLM_POOL_SYSFS_READER_NOLOCK_SHOW(lock_volume_factor, atomic);
210 -LDLM_POOL_SYSFS_WRITER_NOLOCK_STORE(lock_volume_factor, atomic);
211 +static ssize_t lock_volume_factor_show(struct kobject *kobj,
212 + struct attribute *attr,
215 + struct ldlm_pool *pl = container_of(kobj, struct ldlm_pool, pl_kobj);
218 + tmp = (atomic_read(&pl->pl_lock_volume_factor) * 100) >> 8;
219 + return sprintf(buf, "%lu\n", tmp);
222 +static ssize_t lock_volume_factor_store(struct kobject *kobj,
223 + struct attribute *attr,
224 + const char *buffer,
227 + struct ldlm_pool *pl = container_of(kobj, struct ldlm_pool, pl_kobj);
231 + rc = kstrtoul(buffer, 10, &tmp);
236 + tmp = (tmp << 8) / 100;
237 + atomic_set(&pl->pl_lock_volume_factor, tmp);
242 LUSTRE_RW_ATTR(lock_volume_factor);
244 +static ssize_t recalc_time_show(struct kobject *kobj,
245 + struct attribute *attr,
248 + struct ldlm_pool *pl = container_of(kobj, struct ldlm_pool, pl_kobj);
250 + return snprintf(buf, PAGE_SIZE, "%llu\n",
251 + ktime_get_seconds() - pl->pl_recalc_time);
253 +LUSTRE_RO_ATTR(recalc_time);
255 /* These are for pools in /sys/fs/lustre/ldlm/namespaces/.../pool */
256 static struct attribute *ldlm_pl_attrs[] = {
257 &lustre_attr_grant_speed.attr,
258 &lustre_attr_grant_plan.attr,
259 &lustre_attr_recalc_period.attr,
260 &lustre_attr_server_lock_volume.attr,
261 + &lustre_attr_client_lock_volume.attr,
262 + &lustre_attr_recalc_time.attr,
263 &lustre_attr_limit.attr,
264 &lustre_attr_granted.attr,
265 &lustre_attr_cancel_rate.attr,
266 @@ -867,8 +911,8 @@ int ldlm_pool_init(struct ldlm_pool *pl, struct ldlm_namespace *ns,
268 spin_lock_init(&pl->pl_lock);
269 atomic_set(&pl->pl_granted, 0);
270 - pl->pl_recalc_time = ktime_get_real_seconds();
271 - atomic_set(&pl->pl_lock_volume_factor, 1);
272 + pl->pl_recalc_time = ktime_get_seconds();
273 + atomic_set(&pl->pl_lock_volume_factor, 1 << 8);
275 atomic_set(&pl->pl_grant_rate, 0);
276 atomic_set(&pl->pl_cancel_rate, 0);
277 @@ -1222,9 +1266,10 @@ static time64_t ldlm_pools_recalc_delay(enum ldlm_side side)
278 struct ldlm_namespace *ns;
279 struct ldlm_namespace *ns_old = NULL;
280 /* seconds of sleep if no active namespaces */
281 - time64_t delay = side == LDLM_NAMESPACE_SERVER ?
282 - LDLM_POOL_SRV_DEF_RECALC_PERIOD :
283 - LDLM_POOL_CLI_DEF_RECALC_PERIOD;
284 + time64_t delay = ktime_get_seconds() +
285 + (side == LDLM_NAMESPACE_SERVER ?
286 + LDLM_POOL_SRV_DEF_RECALC_PERIOD :
287 + LDLM_POOL_CLI_DEF_RECALC_PERIOD);
290 /* Recalc at least ldlm_namespace_nr(side) namespaces. */
291 @@ -1375,18 +1420,33 @@ static void ldlm_pools_recalc_task(struct work_struct *ws)
292 /* Wake up the blocking threads from time to time. */
293 ldlm_bl_thread_wakeup();
295 + delay -= ktime_get_seconds();
297 + /* Prevent too frequent recalculation. */
298 + CDEBUG(D_DLMTRACE, "Negative interval(%lld)\n", delay);
302 schedule_delayed_work(&ldlm_pools_recalc_work, cfs_time_seconds(delay));
305 int ldlm_pools_init(void)
309 DEF_SHRINKER_VAR(shsvar, ldlm_pools_srv_shrink,
310 ldlm_pools_srv_count, ldlm_pools_srv_scan);
311 DEF_SHRINKER_VAR(shcvar, ldlm_pools_cli_shrink,
312 ldlm_pools_cli_count, ldlm_pools_cli_scan);
314 - schedule_delayed_work(&ldlm_pools_recalc_work,
315 - LDLM_POOL_CLI_DEF_RECALC_PERIOD);
316 +#ifdef HAVE_SERVER_SUPPORT
317 + delay = min(LDLM_POOL_SRV_DEF_RECALC_PERIOD,
318 + LDLM_POOL_CLI_DEF_RECALC_PERIOD);
320 + delay = LDLM_POOL_CLI_DEF_RECALC_PERIOD;
323 + schedule_delayed_work(&ldlm_pools_recalc_work, delay);
324 ldlm_pools_srv_shrinker = set_shrinker(DEFAULT_SEEKS, &shsvar);
325 ldlm_pools_cli_shrinker = set_shrinker(DEFAULT_SEEKS, &shcvar);