Whamcloud - gitweb
feb11d0bd05e659af8ec4b4b1b8afac9aff813d5
[fs/lustre-release.git] / lustre / ldlm / ldlm_pool.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * GPL HEADER START
5  *
6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 only,
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License version 2 for more details (a copy is included
16  * in the LICENSE file that accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License
19  * version 2 along with this program; If not, see
20  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
21  *
22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23  * CA 95054 USA or visit www.sun.com if you need additional information or
24  * have any questions.
25  *
26  * GPL HEADER END
27  */
28 /*
29  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
30  * Use is subject to license terms.
31  *
32  * Copyright (c) 2011, 2012, Whamcloud, Inc.
33  */
34 /*
35  * This file is part of Lustre, http://www.lustre.org/
36  * Lustre is a trademark of Sun Microsystems, Inc.
37  *
38  * lustre/ldlm/ldlm_pool.c
39  *
40  * Author: Yury Umanets <umka@clusterfs.com>
41  */
42
43 /*
44  * Idea of this code is rather simple. Each second, for each server namespace
45  * we have SLV - server lock volume which is calculated on current number of
46  * granted locks, grant speed for past period, etc - that is, locking load.
47  * This SLV number may be thought as a flow definition for simplicity. It is
48  * sent to clients with each occasion to let them know what is current load
49  * situation on the server. By default, at the beginning, SLV on server is
50  * set max value which is calculated as the following: allow to one client
51  * have all locks of limit ->pl_limit for 10h.
52  *
53  * Next, on clients, number of cached locks is not limited artificially in any
54  * way as it was before. Instead, client calculates CLV, that is, client lock
55  * volume for each lock and compares it with last SLV from the server. CLV is
56  * calculated as the number of locks in LRU * lock live time in seconds. If
57  * CLV > SLV - lock is canceled.
58  *
59  * Client has LVF, that is, lock volume factor which regulates how much sensitive
60  * client should be about last SLV from server. The higher LVF is the more locks
61  * will be canceled on client. Default value for it is 1. Setting LVF to 2 means
62  * that client will cancel locks 2 times faster.
63  *
64  * Locks on a client will be canceled more intensively in these cases:
65  * (1) if SLV is smaller, that is, load is higher on the server;
66  * (2) client has a lot of locks (the more locks are held by client, the bigger
67  *     chances that some of them should be canceled);
68  * (3) client has old locks (taken some time ago);
69  *
70  * Thus, according to flow paradigm that we use for better understanding SLV,
71  * CLV is the volume of particle in flow described by SLV. According to this,
72  * if flow is getting thinner, more and more particles become outside of it and
73  * as particles are locks, they should be canceled.
74  *
75  * General idea of this belongs to Vitaly Fertman (vitaly@clusterfs.com). Andreas
76  * Dilger (adilger@clusterfs.com) proposed few nice ideas like using LVF and many
77  * cleanups. Flow definition to allow more easy understanding of the logic belongs
78  * to Nikita Danilov (nikita@clusterfs.com) as well as many cleanups and fixes.
79  * And design and implementation are done by Yury Umanets (umka@clusterfs.com).
80  *
81  * Glossary for terms used:
82  *
83  * pl_limit - Number of allowed locks in pool. Applies to server and client
84  * side (tunable);
85  *
86  * pl_granted - Number of granted locks (calculated);
87  * pl_grant_rate - Number of granted locks for last T (calculated);
88  * pl_cancel_rate - Number of canceled locks for last T (calculated);
89  * pl_grant_speed - Grant speed (GR - CR) for last T (calculated);
90  * pl_grant_plan - Planned number of granted locks for next T (calculated);
91  * pl_server_lock_volume - Current server lock volume (calculated);
92  *
93  * As it may be seen from list above, we have few possible tunables which may
94  * affect behavior much. They all may be modified via proc. However, they also
95  * give a possibility for constructing few pre-defined behavior policies. If
96  * none of predefines is suitable for a working pattern being used, new one may
97  * be "constructed" via proc tunables.
98  */
99
100 #define DEBUG_SUBSYSTEM S_LDLM
101
102 #ifdef __KERNEL__
103 # include <lustre_dlm.h>
104 #else
105 # include <liblustre.h>
106 #endif
107
108 #include <cl_object.h>
109
110 #include <obd_class.h>
111 #include <obd_support.h>
112 #include "ldlm_internal.h"
113
114 #ifdef HAVE_LRU_RESIZE_SUPPORT
115
116 /*
117  * 50 ldlm locks for 1MB of RAM.
118  */
119 #define LDLM_POOL_HOST_L ((CFS_NUM_CACHEPAGES >> (20 - CFS_PAGE_SHIFT)) * 50)
120
121 /*
122  * Maximal possible grant step plan in %.
123  */
124 #define LDLM_POOL_MAX_GSP (30)
125
126 /*
127  * Minimal possible grant step plan in %.
128  */
129 #define LDLM_POOL_MIN_GSP (1)
130
131 /*
132  * This controls the speed of reaching LDLM_POOL_MAX_GSP
133  * with increasing thread period.
134  */
135 #define LDLM_POOL_GSP_STEP_SHIFT (2)
136
137 /*
138  * LDLM_POOL_GSP% of all locks is default GP.
139  */
140 #define LDLM_POOL_GP(L)   (((L) * LDLM_POOL_MAX_GSP) / 100)
141
142 /*
143  * Max age for locks on clients.
144  */
145 #define LDLM_POOL_MAX_AGE (36000)
146
147 /*
148  * The granularity of SLV calculation.
149  */
150 #define LDLM_POOL_SLV_SHIFT (10)
151
152 #ifdef __KERNEL__
153 extern cfs_proc_dir_entry_t *ldlm_ns_proc_dir;
154 #endif
155
156 static inline __u64 dru(__u64 val, __u32 shift, int round_up)
157 {
158         return (val + (round_up ? (1 << shift) - 1 : 0)) >> shift;
159 }
160
161 static inline __u64 ldlm_pool_slv_max(__u32 L)
162 {
163         /*
164          * Allow to have all locks for 1 client for 10 hrs.
165          * Formula is the following: limit * 10h / 1 client.
166          */
167         __u64 lim = (__u64)L *  LDLM_POOL_MAX_AGE / 1;
168         return lim;
169 }
170
171 static inline __u64 ldlm_pool_slv_min(__u32 L)
172 {
173         return 1;
174 }
175
176 enum {
177         LDLM_POOL_FIRST_STAT = 0,
178         LDLM_POOL_GRANTED_STAT = LDLM_POOL_FIRST_STAT,
179         LDLM_POOL_GRANT_STAT,
180         LDLM_POOL_CANCEL_STAT,
181         LDLM_POOL_GRANT_RATE_STAT,
182         LDLM_POOL_CANCEL_RATE_STAT,
183         LDLM_POOL_GRANT_PLAN_STAT,
184         LDLM_POOL_SLV_STAT,
185         LDLM_POOL_SHRINK_REQTD_STAT,
186         LDLM_POOL_SHRINK_FREED_STAT,
187         LDLM_POOL_RECALC_STAT,
188         LDLM_POOL_TIMING_STAT,
189         LDLM_POOL_LAST_STAT
190 };
191
192 static inline struct ldlm_namespace *ldlm_pl2ns(struct ldlm_pool *pl)
193 {
194         return container_of(pl, struct ldlm_namespace, ns_pool);
195 }
196
197 /**
198  * Calculates suggested grant_step in % of available locks for passed
199  * \a period. This is later used in grant_plan calculations.
200  */
201 static inline int ldlm_pool_t2gsp(unsigned int t)
202 {
203         /*
204          * This yields 1% grant step for anything below LDLM_POOL_GSP_STEP
205          * and up to 30% for anything higher than LDLM_POOL_GSP_STEP.
206          *
207          * How this will affect execution is the following:
208          *
209          * - for thread period 1s we will have grant_step 1% which good from
210          * pov of taking some load off from server and push it out to clients.
211          * This is like that because 1% for grant_step means that server will
212          * not allow clients to get lots of locks in short period of time and
213          * keep all old locks in their caches. Clients will always have to
214          * get some locks back if they want to take some new;
215          *
216          * - for thread period 10s (which is default) we will have 23% which
217          * means that clients will have enough of room to take some new locks
218          * without getting some back. All locks from this 23% which were not
219          * taken by clients in current period will contribute in SLV growing.
220          * SLV growing means more locks cached on clients until limit or grant
221          * plan is reached.
222          */
223         return LDLM_POOL_MAX_GSP -
224                 ((LDLM_POOL_MAX_GSP - LDLM_POOL_MIN_GSP) >>
225                  (t >> LDLM_POOL_GSP_STEP_SHIFT));
226 }
227
228 /**
229  * Recalculates next grant limit on passed \a pl.
230  *
231  * \pre ->pl_lock is locked.
232  */
233 static void ldlm_pool_recalc_grant_plan(struct ldlm_pool *pl)
234 {
235         int granted, grant_step, limit;
236
237         limit = ldlm_pool_get_limit(pl);
238         granted = cfs_atomic_read(&pl->pl_granted);
239
240         grant_step = ldlm_pool_t2gsp(pl->pl_recalc_period);
241         grant_step = ((limit - granted) * grant_step) / 100;
242         pl->pl_grant_plan = granted + grant_step;
243         limit = (limit * 5) >> 2;
244         if (pl->pl_grant_plan > limit)
245                 pl->pl_grant_plan = limit;
246 }
247
248 /**
249  * Recalculates next SLV on passed \a pl.
250  *
251  * \pre ->pl_lock is locked.
252  */
253 static void ldlm_pool_recalc_slv(struct ldlm_pool *pl)
254 {
255         int granted;
256         int grant_plan;
257         int round_up;
258         __u64 slv;
259         __u64 slv_factor;
260         __u64 grant_usage;
261         __u32 limit;
262
263         slv = pl->pl_server_lock_volume;
264         grant_plan = pl->pl_grant_plan;
265         limit = ldlm_pool_get_limit(pl);
266         granted = cfs_atomic_read(&pl->pl_granted);
267         round_up = granted < limit;
268
269         grant_usage = max_t(int, limit - (granted - grant_plan), 1);
270
271         /*
272          * Find out SLV change factor which is the ratio of grant usage
273          * from limit. SLV changes as fast as the ratio of grant plan
274          * consumption. The more locks from grant plan are not consumed
275          * by clients in last interval (idle time), the faster grows
276          * SLV. And the opposite, the more grant plan is over-consumed
277          * (load time) the faster drops SLV.
278          */
279         slv_factor = (grant_usage << LDLM_POOL_SLV_SHIFT);
280         do_div(slv_factor, limit);
281         slv = slv * slv_factor;
282         slv = dru(slv, LDLM_POOL_SLV_SHIFT, round_up);
283
284         if (slv > ldlm_pool_slv_max(limit)) {
285                 slv = ldlm_pool_slv_max(limit);
286         } else if (slv < ldlm_pool_slv_min(limit)) {
287                 slv = ldlm_pool_slv_min(limit);
288         }
289
290         pl->pl_server_lock_volume = slv;
291 }
292
293 /**
294  * Recalculates next stats on passed \a pl.
295  *
296  * \pre ->pl_lock is locked.
297  */
298 static void ldlm_pool_recalc_stats(struct ldlm_pool *pl)
299 {
300         int grant_plan = pl->pl_grant_plan;
301         __u64 slv = pl->pl_server_lock_volume;
302         int granted = cfs_atomic_read(&pl->pl_granted);
303         int grant_rate = cfs_atomic_read(&pl->pl_grant_rate);
304         int cancel_rate = cfs_atomic_read(&pl->pl_cancel_rate);
305
306         lprocfs_counter_add(pl->pl_stats, LDLM_POOL_SLV_STAT,
307                             slv);
308         lprocfs_counter_add(pl->pl_stats, LDLM_POOL_GRANTED_STAT,
309                             granted);
310         lprocfs_counter_add(pl->pl_stats, LDLM_POOL_GRANT_RATE_STAT,
311                             grant_rate);
312         lprocfs_counter_add(pl->pl_stats, LDLM_POOL_GRANT_PLAN_STAT,
313                             grant_plan);
314         lprocfs_counter_add(pl->pl_stats, LDLM_POOL_CANCEL_RATE_STAT,
315                             cancel_rate);
316 }
317
318 /**
319  * Sets current SLV into obd accessible via ldlm_pl2ns(pl)->ns_obd.
320  */
321 static void ldlm_srv_pool_push_slv(struct ldlm_pool *pl)
322 {
323         struct obd_device *obd;
324
325         /*
326          * Set new SLV in obd field for using it later without accessing the
327          * pool. This is required to avoid race between sending reply to client
328          * with new SLV and cleanup server stack in which we can't guarantee
329          * that namespace is still alive. We know only that obd is alive as
330          * long as valid export is alive.
331          */
332         obd = ldlm_pl2ns(pl)->ns_obd;
333         LASSERT(obd != NULL);
334         cfs_write_lock(&obd->obd_pool_lock);
335         obd->obd_pool_slv = pl->pl_server_lock_volume;
336         cfs_write_unlock(&obd->obd_pool_lock);
337 }
338
339 /**
340  * Recalculates all pool fields on passed \a pl.
341  *
342  * \pre ->pl_lock is not locked.
343  */
344 static int ldlm_srv_pool_recalc(struct ldlm_pool *pl)
345 {
346         time_t recalc_interval_sec;
347         ENTRY;
348
349         recalc_interval_sec = cfs_time_current_sec() - pl->pl_recalc_time;
350         if (recalc_interval_sec < pl->pl_recalc_period)
351                 RETURN(0);
352
353         cfs_spin_lock(&pl->pl_lock);
354         recalc_interval_sec = cfs_time_current_sec() - pl->pl_recalc_time;
355         if (recalc_interval_sec < pl->pl_recalc_period) {
356                 cfs_spin_unlock(&pl->pl_lock);
357                 RETURN(0);
358         }
359         /*
360          * Recalc SLV after last period. This should be done
361          * _before_ recalculating new grant plan.
362          */
363         ldlm_pool_recalc_slv(pl);
364
365         /*
366          * Make sure that pool informed obd of last SLV changes.
367          */
368         ldlm_srv_pool_push_slv(pl);
369
370         /*
371          * Update grant_plan for new period.
372          */
373         ldlm_pool_recalc_grant_plan(pl);
374
375         pl->pl_recalc_time = cfs_time_current_sec();
376         lprocfs_counter_add(pl->pl_stats, LDLM_POOL_TIMING_STAT,
377                             recalc_interval_sec);
378         cfs_spin_unlock(&pl->pl_lock);
379         RETURN(0);
380 }
381
382 /**
383  * This function is used on server side as main entry point for memory
384  * pressure handling. It decreases SLV on \a pl according to passed
385  * \a nr and \a gfp_mask.
386  *
387  * Our goal here is to decrease SLV such a way that clients hold \a nr
388  * locks smaller in next 10h.
389  */
390 static int ldlm_srv_pool_shrink(struct ldlm_pool *pl,
391                                 int nr, unsigned int gfp_mask)
392 {
393         __u32 limit;
394
395         /*
396          * VM is asking how many entries may be potentially freed.
397          */
398         if (nr == 0)
399                 return cfs_atomic_read(&pl->pl_granted);
400
401         /*
402          * Client already canceled locks but server is already in shrinker
403          * and can't cancel anything. Let's catch this race.
404          */
405         if (cfs_atomic_read(&pl->pl_granted) == 0)
406                 RETURN(0);
407
408         cfs_spin_lock(&pl->pl_lock);
409
410         /*
411          * We want shrinker to possibly cause cancellation of @nr locks from
412          * clients or grant approximately @nr locks smaller next intervals.
413          *
414          * This is why we decreased SLV by @nr. This effect will only be as
415          * long as one re-calc interval (1s these days) and this should be
416          * enough to pass this decreased SLV to all clients. On next recalc
417          * interval pool will either increase SLV if locks load is not high
418          * or will keep on same level or even decrease again, thus, shrinker
419          * decreased SLV will affect next recalc intervals and this way will
420          * make locking load lower.
421          */
422         if (nr < pl->pl_server_lock_volume) {
423                 pl->pl_server_lock_volume = pl->pl_server_lock_volume - nr;
424         } else {
425                 limit = ldlm_pool_get_limit(pl);
426                 pl->pl_server_lock_volume = ldlm_pool_slv_min(limit);
427         }
428
429         /*
430          * Make sure that pool informed obd of last SLV changes.
431          */
432         ldlm_srv_pool_push_slv(pl);
433         cfs_spin_unlock(&pl->pl_lock);
434
435         /*
436          * We did not really free any memory here so far, it only will be
437          * freed later may be, so that we return 0 to not confuse VM.
438          */
439         return 0;
440 }
441
442 /**
443  * Setup server side pool \a pl with passed \a limit.
444  */
445 static int ldlm_srv_pool_setup(struct ldlm_pool *pl, int limit)
446 {
447         struct obd_device *obd;
448
449         obd = ldlm_pl2ns(pl)->ns_obd;
450         LASSERT(obd != NULL && obd != LP_POISON);
451         LASSERT(obd->obd_type != LP_POISON);
452         cfs_write_lock(&obd->obd_pool_lock);
453         obd->obd_pool_limit = limit;
454         cfs_write_unlock(&obd->obd_pool_lock);
455
456         ldlm_pool_set_limit(pl, limit);
457         return 0;
458 }
459
460 /**
461  * Sets SLV and Limit from ldlm_pl2ns(pl)->ns_obd tp passed \a pl.
462  */
463 static void ldlm_cli_pool_pop_slv(struct ldlm_pool *pl)
464 {
465         struct obd_device *obd;
466
467         /*
468          * Get new SLV and Limit from obd which is updated with coming
469          * RPCs.
470          */
471         obd = ldlm_pl2ns(pl)->ns_obd;
472         LASSERT(obd != NULL);
473         cfs_read_lock(&obd->obd_pool_lock);
474         pl->pl_server_lock_volume = obd->obd_pool_slv;
475         ldlm_pool_set_limit(pl, obd->obd_pool_limit);
476         cfs_read_unlock(&obd->obd_pool_lock);
477 }
478
479 /**
480  * Recalculates client size pool \a pl according to current SLV and Limit.
481  */
482 static int ldlm_cli_pool_recalc(struct ldlm_pool *pl)
483 {
484         time_t recalc_interval_sec;
485         ENTRY;
486
487         recalc_interval_sec = cfs_time_current_sec() - pl->pl_recalc_time;
488         if (recalc_interval_sec < pl->pl_recalc_period)
489                 RETURN(0);
490
491         cfs_spin_lock(&pl->pl_lock);
492         /*
493          * Check if we need to recalc lists now.
494          */
495         recalc_interval_sec = cfs_time_current_sec() - pl->pl_recalc_time;
496         if (recalc_interval_sec < pl->pl_recalc_period) {
497                 cfs_spin_unlock(&pl->pl_lock);
498                 RETURN(0);
499         }
500
501         /*
502          * Make sure that pool knows last SLV and Limit from obd.
503          */
504         ldlm_cli_pool_pop_slv(pl);
505
506         pl->pl_recalc_time = cfs_time_current_sec();
507         lprocfs_counter_add(pl->pl_stats, LDLM_POOL_TIMING_STAT,
508                             recalc_interval_sec);
509         cfs_spin_unlock(&pl->pl_lock);
510
511         /*
512          * Do not cancel locks in case lru resize is disabled for this ns.
513          */
514         if (!ns_connect_lru_resize(ldlm_pl2ns(pl)))
515                 RETURN(0);
516
517         /*
518          * In the time of canceling locks on client we do not need to maintain
519          * sharp timing, we only want to cancel locks asap according to new SLV.
520          * It may be called when SLV has changed much, this is why we do not
521          * take into account pl->pl_recalc_time here.
522          */
523         RETURN(ldlm_cancel_lru(ldlm_pl2ns(pl), 0, LDLM_SYNC, 
524                                LDLM_CANCEL_LRUR));
525 }
526
527 /**
528  * This function is main entry point for memory pressure handling on client
529  * side.  Main goal of this function is to cancel some number of locks on
530  * passed \a pl according to \a nr and \a gfp_mask.
531  */
532 static int ldlm_cli_pool_shrink(struct ldlm_pool *pl,
533                                 int nr, unsigned int gfp_mask)
534 {
535         struct ldlm_namespace *ns;
536         int canceled = 0, unused;
537
538         ns = ldlm_pl2ns(pl);
539
540         /*
541          * Do not cancel locks in case lru resize is disabled for this ns.
542          */
543         if (!ns_connect_lru_resize(ns))
544                 RETURN(0);
545
546         /*
547          * Make sure that pool knows last SLV and Limit from obd.
548          */
549         ldlm_cli_pool_pop_slv(pl);
550
551         cfs_spin_lock(&ns->ns_lock);
552         unused = ns->ns_nr_unused;
553         cfs_spin_unlock(&ns->ns_lock);
554         
555         if (nr) {
556                 canceled = ldlm_cancel_lru(ns, nr, LDLM_ASYNC,
557                                            LDLM_CANCEL_SHRINK);
558         }
559 #ifdef __KERNEL__
560         /*
561          * Return the number of potentially reclaimable locks.
562          */
563         return ((unused - canceled) / 100) * sysctl_vfs_cache_pressure;
564 #else
565         return unused - canceled;
566 #endif
567 }
568
569 struct ldlm_pool_ops ldlm_srv_pool_ops = {
570         .po_recalc = ldlm_srv_pool_recalc,
571         .po_shrink = ldlm_srv_pool_shrink,
572         .po_setup  = ldlm_srv_pool_setup
573 };
574
575 struct ldlm_pool_ops ldlm_cli_pool_ops = {
576         .po_recalc = ldlm_cli_pool_recalc,
577         .po_shrink = ldlm_cli_pool_shrink
578 };
579
580 /**
581  * Pool recalc wrapper. Will call either client or server pool recalc callback
582  * depending what pool \a pl is used.
583  */
584 int ldlm_pool_recalc(struct ldlm_pool *pl)
585 {
586         time_t recalc_interval_sec;
587         int count;
588
589         recalc_interval_sec = cfs_time_current_sec() - pl->pl_recalc_time;
590         if (recalc_interval_sec <= 0)
591                 goto recalc;
592
593         cfs_spin_lock(&pl->pl_lock);
594         recalc_interval_sec = cfs_time_current_sec() - pl->pl_recalc_time;
595         if (recalc_interval_sec > 0) {
596                 /*
597                  * Update pool statistics every 1s.
598                  */
599                 ldlm_pool_recalc_stats(pl);
600
601                 /*
602                  * Zero out all rates and speed for the last period.
603                  */
604                 cfs_atomic_set(&pl->pl_grant_rate, 0);
605                 cfs_atomic_set(&pl->pl_cancel_rate, 0);
606         }
607         cfs_spin_unlock(&pl->pl_lock);
608
609  recalc:
610         if (pl->pl_ops->po_recalc != NULL) {
611                 count = pl->pl_ops->po_recalc(pl);
612                 lprocfs_counter_add(pl->pl_stats, LDLM_POOL_RECALC_STAT,
613                                     count);
614                 return count;
615         }
616
617         return 0;
618 }
619 EXPORT_SYMBOL(ldlm_pool_recalc);
620
621 /**
622  * Pool shrink wrapper. Will call either client or server pool recalc callback
623  * depending what pool \a pl is used.
624  */
625 int ldlm_pool_shrink(struct ldlm_pool *pl, int nr,
626                      unsigned int gfp_mask)
627 {
628         int cancel = 0;
629
630         if (pl->pl_ops->po_shrink != NULL) {
631                 cancel = pl->pl_ops->po_shrink(pl, nr, gfp_mask);
632                 if (nr > 0) {
633                         lprocfs_counter_add(pl->pl_stats,
634                                             LDLM_POOL_SHRINK_REQTD_STAT,
635                                             nr);
636                         lprocfs_counter_add(pl->pl_stats,
637                                             LDLM_POOL_SHRINK_FREED_STAT,
638                                             cancel);
639                         CDEBUG(D_DLMTRACE, "%s: request to shrink %d locks, "
640                                "shrunk %d\n", pl->pl_name, nr, cancel);
641                 }
642         }
643         return cancel;
644 }
645 EXPORT_SYMBOL(ldlm_pool_shrink);
646
647 /**
648  * Pool setup wrapper. Will call either client or server pool recalc callback
649  * depending what pool \a pl is used.
650  *
651  * Sets passed \a limit into pool \a pl.
652  */
653 int ldlm_pool_setup(struct ldlm_pool *pl, int limit)
654 {
655         if (pl->pl_ops->po_setup != NULL)
656                 return(pl->pl_ops->po_setup(pl, limit));
657         return 0;
658 }
659 EXPORT_SYMBOL(ldlm_pool_setup);
660
661 #ifdef __KERNEL__
662 static int lprocfs_rd_pool_state(char *page, char **start, off_t off,
663                                  int count, int *eof, void *data)
664 {
665         int granted, grant_rate, cancel_rate, grant_step;
666         int nr = 0, grant_speed, grant_plan, lvf;
667         struct ldlm_pool *pl = data;
668         __u64 slv, clv;
669         __u32 limit;
670
671         cfs_spin_lock(&pl->pl_lock);
672         slv = pl->pl_server_lock_volume;
673         clv = pl->pl_client_lock_volume;
674         limit = ldlm_pool_get_limit(pl);
675         grant_plan = pl->pl_grant_plan;
676         granted = cfs_atomic_read(&pl->pl_granted);
677         grant_rate = cfs_atomic_read(&pl->pl_grant_rate);
678         cancel_rate = cfs_atomic_read(&pl->pl_cancel_rate);
679         grant_speed = grant_rate - cancel_rate;
680         lvf = cfs_atomic_read(&pl->pl_lock_volume_factor);
681         grant_step = ldlm_pool_t2gsp(pl->pl_recalc_period);
682         cfs_spin_unlock(&pl->pl_lock);
683
684         nr += snprintf(page + nr, count - nr, "LDLM pool state (%s):\n",
685                        pl->pl_name);
686         nr += snprintf(page + nr, count - nr, "  SLV: "LPU64"\n", slv);
687         nr += snprintf(page + nr, count - nr, "  CLV: "LPU64"\n", clv);
688         nr += snprintf(page + nr, count - nr, "  LVF: %d\n", lvf);
689
690         if (ns_is_server(ldlm_pl2ns(pl))) {
691                 nr += snprintf(page + nr, count - nr, "  GSP: %d%%\n",
692                                grant_step);
693                 nr += snprintf(page + nr, count - nr, "  GP:  %d\n",
694                                grant_plan);
695         }
696         nr += snprintf(page + nr, count - nr, "  GR:  %d\n",
697                        grant_rate);
698         nr += snprintf(page + nr, count - nr, "  CR:  %d\n",
699                        cancel_rate);
700         nr += snprintf(page + nr, count - nr, "  GS:  %d\n",
701                        grant_speed);
702         nr += snprintf(page + nr, count - nr, "  G:   %d\n",
703                        granted);
704         nr += snprintf(page + nr, count - nr, "  L:   %d\n",
705                        limit);
706         return nr;
707 }
708
709 static int lprocfs_rd_grant_speed(char *page, char **start, off_t off,
710                                   int count, int *eof, void *data)
711 {
712         struct ldlm_pool *pl = data;
713         int               grant_speed;
714
715         cfs_spin_lock(&pl->pl_lock);
716         /* serialize with ldlm_pool_recalc */
717         grant_speed = cfs_atomic_read(&pl->pl_grant_rate) -
718                       cfs_atomic_read(&pl->pl_cancel_rate);
719         cfs_spin_unlock(&pl->pl_lock);
720         return lprocfs_rd_uint(page, start, off, count, eof, &grant_speed);
721 }
722
723 LDLM_POOL_PROC_READER(grant_plan, int);
724 LDLM_POOL_PROC_READER(recalc_period, int);
725 LDLM_POOL_PROC_WRITER(recalc_period, int);
726
727 static int ldlm_pool_proc_init(struct ldlm_pool *pl)
728 {
729         struct ldlm_namespace *ns = ldlm_pl2ns(pl);
730         struct proc_dir_entry *parent_ns_proc;
731         struct lprocfs_vars pool_vars[2];
732         char *var_name = NULL;
733         int rc = 0;
734         ENTRY;
735
736         OBD_ALLOC(var_name, MAX_STRING_SIZE + 1);
737         if (!var_name)
738                 RETURN(-ENOMEM);
739
740         parent_ns_proc = lprocfs_srch(ldlm_ns_proc_dir,
741                                       ldlm_ns_name(ns));
742         if (parent_ns_proc == NULL) {
743                 CERROR("%s: proc entry is not initialized\n",
744                        ldlm_ns_name(ns));
745                 GOTO(out_free_name, rc = -EINVAL);
746         }
747         pl->pl_proc_dir = lprocfs_register("pool", parent_ns_proc,
748                                            NULL, NULL);
749         if (IS_ERR(pl->pl_proc_dir)) {
750                 CERROR("LProcFS failed in ldlm-pool-init\n");
751                 rc = PTR_ERR(pl->pl_proc_dir);
752                 GOTO(out_free_name, rc);
753         }
754
755         var_name[MAX_STRING_SIZE] = '\0';
756         memset(pool_vars, 0, sizeof(pool_vars));
757         pool_vars[0].name = var_name;
758
759         snprintf(var_name, MAX_STRING_SIZE, "server_lock_volume");
760         pool_vars[0].data = &pl->pl_server_lock_volume;
761         pool_vars[0].read_fptr = lprocfs_rd_u64;
762         lprocfs_add_vars(pl->pl_proc_dir, pool_vars, 0);
763
764         snprintf(var_name, MAX_STRING_SIZE, "limit");
765         pool_vars[0].data = &pl->pl_limit;
766         pool_vars[0].read_fptr = lprocfs_rd_atomic;
767         pool_vars[0].write_fptr = lprocfs_wr_atomic;
768         lprocfs_add_vars(pl->pl_proc_dir, pool_vars, 0);
769
770         snprintf(var_name, MAX_STRING_SIZE, "granted");
771         pool_vars[0].data = &pl->pl_granted;
772         pool_vars[0].read_fptr = lprocfs_rd_atomic;
773         lprocfs_add_vars(pl->pl_proc_dir, pool_vars, 0);
774
775         snprintf(var_name, MAX_STRING_SIZE, "grant_speed");
776         pool_vars[0].data = pl;
777         pool_vars[0].read_fptr = lprocfs_rd_grant_speed;
778         lprocfs_add_vars(pl->pl_proc_dir, pool_vars, 0);
779
780         snprintf(var_name, MAX_STRING_SIZE, "cancel_rate");
781         pool_vars[0].data = &pl->pl_cancel_rate;
782         pool_vars[0].read_fptr = lprocfs_rd_atomic;
783         lprocfs_add_vars(pl->pl_proc_dir, pool_vars, 0);
784
785         snprintf(var_name, MAX_STRING_SIZE, "grant_rate");
786         pool_vars[0].data = &pl->pl_grant_rate;
787         pool_vars[0].read_fptr = lprocfs_rd_atomic;
788         lprocfs_add_vars(pl->pl_proc_dir, pool_vars, 0);
789
790         snprintf(var_name, MAX_STRING_SIZE, "grant_plan");
791         pool_vars[0].data = pl;
792         pool_vars[0].read_fptr = lprocfs_rd_grant_plan;
793         lprocfs_add_vars(pl->pl_proc_dir, pool_vars, 0);
794
795         snprintf(var_name, MAX_STRING_SIZE, "recalc_period");
796         pool_vars[0].data = pl;
797         pool_vars[0].read_fptr = lprocfs_rd_recalc_period;
798         pool_vars[0].write_fptr = lprocfs_wr_recalc_period;
799         lprocfs_add_vars(pl->pl_proc_dir, pool_vars, 0);
800
801         snprintf(var_name, MAX_STRING_SIZE, "lock_volume_factor");
802         pool_vars[0].data = &pl->pl_lock_volume_factor;
803         pool_vars[0].read_fptr = lprocfs_rd_atomic;
804         pool_vars[0].write_fptr = lprocfs_wr_atomic;
805         lprocfs_add_vars(pl->pl_proc_dir, pool_vars, 0);
806
807         snprintf(var_name, MAX_STRING_SIZE, "state");
808         pool_vars[0].data = pl;
809         pool_vars[0].read_fptr = lprocfs_rd_pool_state;
810         lprocfs_add_vars(pl->pl_proc_dir, pool_vars, 0);
811
812         pl->pl_stats = lprocfs_alloc_stats(LDLM_POOL_LAST_STAT -
813                                            LDLM_POOL_FIRST_STAT, 0);
814         if (!pl->pl_stats)
815                 GOTO(out_free_name, rc = -ENOMEM);
816
817         lprocfs_counter_init(pl->pl_stats, LDLM_POOL_GRANTED_STAT,
818                              LPROCFS_CNTR_AVGMINMAX | LPROCFS_CNTR_STDDEV,
819                              "granted", "locks");
820         lprocfs_counter_init(pl->pl_stats, LDLM_POOL_GRANT_STAT,
821                              LPROCFS_CNTR_AVGMINMAX | LPROCFS_CNTR_STDDEV,
822                              "grant", "locks");
823         lprocfs_counter_init(pl->pl_stats, LDLM_POOL_CANCEL_STAT,
824                              LPROCFS_CNTR_AVGMINMAX | LPROCFS_CNTR_STDDEV,
825                              "cancel", "locks");
826         lprocfs_counter_init(pl->pl_stats, LDLM_POOL_GRANT_RATE_STAT,
827                              LPROCFS_CNTR_AVGMINMAX | LPROCFS_CNTR_STDDEV,
828                              "grant_rate", "locks/s");
829         lprocfs_counter_init(pl->pl_stats, LDLM_POOL_CANCEL_RATE_STAT,
830                              LPROCFS_CNTR_AVGMINMAX | LPROCFS_CNTR_STDDEV,
831                              "cancel_rate", "locks/s");
832         lprocfs_counter_init(pl->pl_stats, LDLM_POOL_GRANT_PLAN_STAT,
833                              LPROCFS_CNTR_AVGMINMAX | LPROCFS_CNTR_STDDEV,
834                              "grant_plan", "locks/s");
835         lprocfs_counter_init(pl->pl_stats, LDLM_POOL_SLV_STAT,
836                              LPROCFS_CNTR_AVGMINMAX | LPROCFS_CNTR_STDDEV,
837                              "slv", "slv");
838         lprocfs_counter_init(pl->pl_stats, LDLM_POOL_SHRINK_REQTD_STAT,
839                              LPROCFS_CNTR_AVGMINMAX | LPROCFS_CNTR_STDDEV,
840                              "shrink_request", "locks");
841         lprocfs_counter_init(pl->pl_stats, LDLM_POOL_SHRINK_FREED_STAT,
842                              LPROCFS_CNTR_AVGMINMAX | LPROCFS_CNTR_STDDEV,
843                              "shrink_freed", "locks");
844         lprocfs_counter_init(pl->pl_stats, LDLM_POOL_RECALC_STAT,
845                              LPROCFS_CNTR_AVGMINMAX | LPROCFS_CNTR_STDDEV,
846                              "recalc_freed", "locks");
847         lprocfs_counter_init(pl->pl_stats, LDLM_POOL_TIMING_STAT,
848                              LPROCFS_CNTR_AVGMINMAX | LPROCFS_CNTR_STDDEV,
849                              "recalc_timing", "sec");
850         lprocfs_register_stats(pl->pl_proc_dir, "stats", pl->pl_stats);
851
852         EXIT;
853 out_free_name:
854         OBD_FREE(var_name, MAX_STRING_SIZE + 1);
855         return rc;
856 }
857
858 static void ldlm_pool_proc_fini(struct ldlm_pool *pl)
859 {
860         if (pl->pl_stats != NULL) {
861                 lprocfs_free_stats(&pl->pl_stats);
862                 pl->pl_stats = NULL;
863         }
864         if (pl->pl_proc_dir != NULL) {
865                 lprocfs_remove(&pl->pl_proc_dir);
866                 pl->pl_proc_dir = NULL;
867         }
868 }
869 #else /* !__KERNEL__*/
870 #define ldlm_pool_proc_init(pl) (0)
871 #define ldlm_pool_proc_fini(pl) while (0) {}
872 #endif
873
874 int ldlm_pool_init(struct ldlm_pool *pl, struct ldlm_namespace *ns,
875                    int idx, ldlm_side_t client)
876 {
877         int rc;
878         ENTRY;
879
880         cfs_spin_lock_init(&pl->pl_lock);
881         cfs_atomic_set(&pl->pl_granted, 0);
882         pl->pl_recalc_time = cfs_time_current_sec();
883         cfs_atomic_set(&pl->pl_lock_volume_factor, 1);
884
885         cfs_atomic_set(&pl->pl_grant_rate, 0);
886         cfs_atomic_set(&pl->pl_cancel_rate, 0);
887         pl->pl_grant_plan = LDLM_POOL_GP(LDLM_POOL_HOST_L);
888
889         snprintf(pl->pl_name, sizeof(pl->pl_name), "ldlm-pool-%s-%d",
890                  ldlm_ns_name(ns), idx);
891
892         if (client == LDLM_NAMESPACE_SERVER) {
893                 pl->pl_ops = &ldlm_srv_pool_ops;
894                 ldlm_pool_set_limit(pl, LDLM_POOL_HOST_L);
895                 pl->pl_recalc_period = LDLM_POOL_SRV_DEF_RECALC_PERIOD;
896                 pl->pl_server_lock_volume = ldlm_pool_slv_max(LDLM_POOL_HOST_L);
897         } else {
898                 ldlm_pool_set_limit(pl, 1);
899                 pl->pl_server_lock_volume = 0;
900                 pl->pl_ops = &ldlm_cli_pool_ops;
901                 pl->pl_recalc_period = LDLM_POOL_CLI_DEF_RECALC_PERIOD;
902         }
903         pl->pl_client_lock_volume = 0;
904         rc = ldlm_pool_proc_init(pl);
905         if (rc)
906                 RETURN(rc);
907
908         CDEBUG(D_DLMTRACE, "Lock pool %s is initialized\n", pl->pl_name);
909
910         RETURN(rc);
911 }
912 EXPORT_SYMBOL(ldlm_pool_init);
913
914 void ldlm_pool_fini(struct ldlm_pool *pl)
915 {
916         ENTRY;
917         ldlm_pool_proc_fini(pl);
918
919         /*
920          * Pool should not be used after this point. We can't free it here as
921          * it lives in struct ldlm_namespace, but still interested in catching
922          * any abnormal using cases.
923          */
924         POISON(pl, 0x5a, sizeof(*pl));
925         EXIT;
926 }
927 EXPORT_SYMBOL(ldlm_pool_fini);
928
929 /**
930  * Add new taken ldlm lock \a lock into pool \a pl accounting.
931  */
932 void ldlm_pool_add(struct ldlm_pool *pl, struct ldlm_lock *lock)
933 {
934         /*
935          * FLOCK locks are special in a sense that they are almost never
936          * cancelled, instead special kind of lock is used to drop them.
937          * also there is no LRU for flock locks, so no point in tracking
938          * them anyway.
939          */
940         if (lock->l_resource->lr_type == LDLM_FLOCK)
941                 return;
942
943         cfs_atomic_inc(&pl->pl_granted);
944         cfs_atomic_inc(&pl->pl_grant_rate);
945         lprocfs_counter_incr(pl->pl_stats, LDLM_POOL_GRANT_STAT);
946         /*
947          * Do not do pool recalc for client side as all locks which
948          * potentially may be canceled has already been packed into
949          * enqueue/cancel rpc. Also we do not want to run out of stack
950          * with too long call paths.
951          */
952         if (ns_is_server(ldlm_pl2ns(pl)))
953                 ldlm_pool_recalc(pl);
954 }
955 EXPORT_SYMBOL(ldlm_pool_add);
956
957 /**
958  * Remove ldlm lock \a lock from pool \a pl accounting.
959  */
960 void ldlm_pool_del(struct ldlm_pool *pl, struct ldlm_lock *lock)
961 {
962         /*
963          * Filter out FLOCK locks. Read above comment in ldlm_pool_add().
964          */
965         if (lock->l_resource->lr_type == LDLM_FLOCK)
966                 return;
967
968         LASSERT(cfs_atomic_read(&pl->pl_granted) > 0);
969         cfs_atomic_dec(&pl->pl_granted);
970         cfs_atomic_inc(&pl->pl_cancel_rate);
971
972         lprocfs_counter_incr(pl->pl_stats, LDLM_POOL_CANCEL_STAT);
973
974         if (ns_is_server(ldlm_pl2ns(pl)))
975                 ldlm_pool_recalc(pl);
976 }
977 EXPORT_SYMBOL(ldlm_pool_del);
978
979 /**
980  * Returns current \a pl SLV.
981  *
982  * \pre ->pl_lock is not locked.
983  */
984 __u64 ldlm_pool_get_slv(struct ldlm_pool *pl)
985 {
986         __u64 slv;
987         cfs_spin_lock(&pl->pl_lock);
988         slv = pl->pl_server_lock_volume;
989         cfs_spin_unlock(&pl->pl_lock);
990         return slv;
991 }
992 EXPORT_SYMBOL(ldlm_pool_get_slv);
993
994 /**
995  * Sets passed \a slv to \a pl.
996  *
997  * \pre ->pl_lock is not locked.
998  */
999 void ldlm_pool_set_slv(struct ldlm_pool *pl, __u64 slv)
1000 {
1001         cfs_spin_lock(&pl->pl_lock);
1002         pl->pl_server_lock_volume = slv;
1003         cfs_spin_unlock(&pl->pl_lock);
1004 }
1005 EXPORT_SYMBOL(ldlm_pool_set_slv);
1006
1007 /**
1008  * Returns current \a pl CLV.
1009  *
1010  * \pre ->pl_lock is not locked.
1011  */
1012 __u64 ldlm_pool_get_clv(struct ldlm_pool *pl)
1013 {
1014         __u64 slv;
1015         cfs_spin_lock(&pl->pl_lock);
1016         slv = pl->pl_client_lock_volume;
1017         cfs_spin_unlock(&pl->pl_lock);
1018         return slv;
1019 }
1020 EXPORT_SYMBOL(ldlm_pool_get_clv);
1021
1022 /**
1023  * Sets passed \a clv to \a pl.
1024  *
1025  * \pre ->pl_lock is not locked.
1026  */
1027 void ldlm_pool_set_clv(struct ldlm_pool *pl, __u64 clv)
1028 {
1029         cfs_spin_lock(&pl->pl_lock);
1030         pl->pl_client_lock_volume = clv;
1031         cfs_spin_unlock(&pl->pl_lock);
1032 }
1033 EXPORT_SYMBOL(ldlm_pool_set_clv);
1034
1035 /**
1036  * Returns current \a pl limit.
1037  */
1038 __u32 ldlm_pool_get_limit(struct ldlm_pool *pl)
1039 {
1040         return cfs_atomic_read(&pl->pl_limit);
1041 }
1042 EXPORT_SYMBOL(ldlm_pool_get_limit);
1043
1044 /**
1045  * Sets passed \a limit to \a pl.
1046  */
1047 void ldlm_pool_set_limit(struct ldlm_pool *pl, __u32 limit)
1048 {
1049         cfs_atomic_set(&pl->pl_limit, limit);
1050 }
1051 EXPORT_SYMBOL(ldlm_pool_set_limit);
1052
1053 /**
1054  * Returns current LVF from \a pl.
1055  */
1056 __u32 ldlm_pool_get_lvf(struct ldlm_pool *pl)
1057 {
1058         return cfs_atomic_read(&pl->pl_lock_volume_factor);
1059 }
1060 EXPORT_SYMBOL(ldlm_pool_get_lvf);
1061
1062 #ifdef __KERNEL__
1063 static int ldlm_pool_granted(struct ldlm_pool *pl)
1064 {
1065         return cfs_atomic_read(&pl->pl_granted);
1066 }
1067
1068 static struct ptlrpc_thread *ldlm_pools_thread;
1069 static struct cfs_shrinker *ldlm_pools_srv_shrinker;
1070 static struct cfs_shrinker *ldlm_pools_cli_shrinker;
1071 static cfs_completion_t ldlm_pools_comp;
1072
1073 /*
1074  * Cancel \a nr locks from all namespaces (if possible). Returns number of
1075  * cached locks after shrink is finished. All namespaces are asked to
1076  * cancel approximately equal amount of locks to keep balancing.
1077  */
1078 static int ldlm_pools_shrink(ldlm_side_t client, int nr,
1079                              unsigned int gfp_mask)
1080 {
1081         int total = 0, cached = 0, nr_ns;
1082         struct ldlm_namespace *ns;
1083         void *cookie;
1084
1085         if (client == LDLM_NAMESPACE_CLIENT && nr != 0 &&
1086             !(gfp_mask & __GFP_FS))
1087                 return -1;
1088
1089         CDEBUG(D_DLMTRACE, "Request to shrink %d %s locks from all pools\n",
1090                nr, client == LDLM_NAMESPACE_CLIENT ? "client" : "server");
1091
1092         cookie = cl_env_reenter();
1093
1094         /*
1095          * Find out how many resources we may release.
1096          */
1097         for (nr_ns = cfs_atomic_read(ldlm_namespace_nr(client));
1098              nr_ns > 0; nr_ns--)
1099         {
1100                 cfs_mutex_lock(ldlm_namespace_lock(client));
1101                 if (cfs_list_empty(ldlm_namespace_list(client))) {
1102                         cfs_mutex_unlock(ldlm_namespace_lock(client));
1103                         cl_env_reexit(cookie);
1104                         return 0;
1105                 }
1106                 ns = ldlm_namespace_first_locked(client);
1107                 ldlm_namespace_get(ns);
1108                 ldlm_namespace_move_locked(ns, client);
1109                 cfs_mutex_unlock(ldlm_namespace_lock(client));
1110                 total += ldlm_pool_shrink(&ns->ns_pool, 0, gfp_mask);
1111                 ldlm_namespace_put(ns);
1112         }
1113
1114         if (nr == 0 || total == 0) {
1115                 cl_env_reexit(cookie);
1116                 return total;
1117         }
1118
1119         /*
1120          * Shrink at least ldlm_namespace_nr(client) namespaces.
1121          */
1122         for (nr_ns = cfs_atomic_read(ldlm_namespace_nr(client));
1123              nr_ns > 0; nr_ns--)
1124         {
1125                 int cancel, nr_locks;
1126
1127                 /*
1128                  * Do not call shrink under ldlm_namespace_lock(client)
1129                  */
1130                 cfs_mutex_lock(ldlm_namespace_lock(client));
1131                 if (cfs_list_empty(ldlm_namespace_list(client))) {
1132                         cfs_mutex_unlock(ldlm_namespace_lock(client));
1133                         /*
1134                          * If list is empty, we can't return any @cached > 0,
1135                          * that probably would cause needless shrinker
1136                          * call.
1137                          */
1138                         cached = 0;
1139                         break;
1140                 }
1141                 ns = ldlm_namespace_first_locked(client);
1142                 ldlm_namespace_get(ns);
1143                 ldlm_namespace_move_locked(ns, client);
1144                 cfs_mutex_unlock(ldlm_namespace_lock(client));
1145
1146                 nr_locks = ldlm_pool_granted(&ns->ns_pool);
1147                 cancel = 1 + nr_locks * nr / total;
1148                 ldlm_pool_shrink(&ns->ns_pool, cancel, gfp_mask);
1149                 cached += ldlm_pool_granted(&ns->ns_pool);
1150                 ldlm_namespace_put(ns);
1151         }
1152         cl_env_reexit(cookie);
1153         /* we only decrease the SLV in server pools shrinker, return -1 to
1154          * kernel to avoid needless loop. LU-1128 */
1155         return (client == LDLM_NAMESPACE_SERVER) ? -1 : cached;
1156 }
1157
1158 static int ldlm_pools_srv_shrink(SHRINKER_ARGS(sc, nr_to_scan, gfp_mask))
1159 {
1160         return ldlm_pools_shrink(LDLM_NAMESPACE_SERVER,
1161                                  shrink_param(sc, nr_to_scan),
1162                                  shrink_param(sc, gfp_mask));
1163 }
1164
1165 static int ldlm_pools_cli_shrink(SHRINKER_ARGS(sc, nr_to_scan, gfp_mask))
1166 {
1167         return ldlm_pools_shrink(LDLM_NAMESPACE_CLIENT,
1168                                  shrink_param(sc, nr_to_scan),
1169                                  shrink_param(sc, gfp_mask));
1170 }
1171
1172 void ldlm_pools_recalc(ldlm_side_t client)
1173 {
1174         __u32 nr_l = 0, nr_p = 0, l;
1175         struct ldlm_namespace *ns;
1176         int nr, equal = 0;
1177
1178         /*
1179          * No need to setup pool limit for client pools.
1180          */
1181         if (client == LDLM_NAMESPACE_SERVER) {
1182                 /*
1183                  * Check all modest namespaces first.
1184                  */
1185                 cfs_mutex_lock(ldlm_namespace_lock(client));
1186                 cfs_list_for_each_entry(ns, ldlm_namespace_list(client),
1187                                         ns_list_chain)
1188                 {
1189                         if (ns->ns_appetite != LDLM_NAMESPACE_MODEST)
1190                                 continue;
1191
1192                         l = ldlm_pool_granted(&ns->ns_pool);
1193                         if (l == 0)
1194                                 l = 1;
1195
1196                         /*
1197                          * Set the modest pools limit equal to their avg granted
1198                          * locks + ~6%.
1199                          */
1200                         l += dru(l, LDLM_POOLS_MODEST_MARGIN_SHIFT, 0);
1201                         ldlm_pool_setup(&ns->ns_pool, l);
1202                         nr_l += l;
1203                         nr_p++;
1204                 }
1205
1206                 /*
1207                  * Make sure that modest namespaces did not eat more that 2/3
1208                  * of limit.
1209                  */
1210                 if (nr_l >= 2 * (LDLM_POOL_HOST_L / 3)) {
1211                         CWARN("\"Modest\" pools eat out 2/3 of server locks "
1212                               "limit (%d of %lu). This means that you have too "
1213                               "many clients for this amount of server RAM. "
1214                               "Upgrade server!\n", nr_l, LDLM_POOL_HOST_L);
1215                         equal = 1;
1216                 }
1217
1218                 /*
1219                  * The rest is given to greedy namespaces.
1220                  */
1221                 cfs_list_for_each_entry(ns, ldlm_namespace_list(client),
1222                                         ns_list_chain)
1223                 {
1224                         if (!equal && ns->ns_appetite != LDLM_NAMESPACE_GREEDY)
1225                                 continue;
1226
1227                         if (equal) {
1228                                 /*
1229                                  * In the case 2/3 locks are eaten out by
1230                                  * modest pools, we re-setup equal limit
1231                                  * for _all_ pools.
1232                                  */
1233                                 l = LDLM_POOL_HOST_L /
1234                                         cfs_atomic_read(
1235                                                 ldlm_namespace_nr(client));
1236                         } else {
1237                                 /*
1238                                  * All the rest of greedy pools will have
1239                                  * all locks in equal parts.
1240                                  */
1241                                 l = (LDLM_POOL_HOST_L - nr_l) /
1242                                         (cfs_atomic_read(
1243                                                 ldlm_namespace_nr(client)) -
1244                                          nr_p);
1245                         }
1246                         ldlm_pool_setup(&ns->ns_pool, l);
1247                 }
1248                 cfs_mutex_unlock(ldlm_namespace_lock(client));
1249         }
1250
1251         /*
1252          * Recalc at least ldlm_namespace_nr(client) namespaces.
1253          */
1254         for (nr = cfs_atomic_read(ldlm_namespace_nr(client)); nr > 0; nr--) {
1255                 int     skip;
1256                 /*
1257                  * Lock the list, get first @ns in the list, getref, move it
1258                  * to the tail, unlock and call pool recalc. This way we avoid
1259                  * calling recalc under @ns lock what is really good as we get
1260                  * rid of potential deadlock on client nodes when canceling
1261                  * locks synchronously.
1262                  */
1263                 cfs_mutex_lock(ldlm_namespace_lock(client));
1264                 if (cfs_list_empty(ldlm_namespace_list(client))) {
1265                         cfs_mutex_unlock(ldlm_namespace_lock(client));
1266                         break;
1267                 }
1268                 ns = ldlm_namespace_first_locked(client);
1269
1270                 cfs_spin_lock(&ns->ns_lock);
1271                 /*
1272                  * skip ns which is being freed, and we don't want to increase
1273                  * its refcount again, not even temporarily. bz21519 & LU-499.
1274                  */
1275                 if (ns->ns_stopping) {
1276                         skip = 1;
1277                 } else {
1278                         skip = 0;
1279                         ldlm_namespace_get(ns);
1280                 }
1281                 cfs_spin_unlock(&ns->ns_lock);
1282
1283                 ldlm_namespace_move_locked(ns, client);
1284                 cfs_mutex_unlock(ldlm_namespace_lock(client));
1285
1286                 /*
1287                  * After setup is done - recalc the pool.
1288                  */
1289                 if (!skip) {
1290                         ldlm_pool_recalc(&ns->ns_pool);
1291                         ldlm_namespace_put(ns);
1292                 }
1293         }
1294 }
1295 EXPORT_SYMBOL(ldlm_pools_recalc);
1296
1297 static int ldlm_pools_thread_main(void *arg)
1298 {
1299         struct ptlrpc_thread *thread = (struct ptlrpc_thread *)arg;
1300         char *t_name = "ldlm_poold";
1301         ENTRY;
1302
1303         cfs_daemonize(t_name);
1304         thread_set_flags(thread, SVC_RUNNING);
1305         cfs_waitq_signal(&thread->t_ctl_waitq);
1306
1307         CDEBUG(D_DLMTRACE, "%s: pool thread starting, process %d\n",
1308                t_name, cfs_curproc_pid());
1309
1310         while (1) {
1311                 struct l_wait_info lwi;
1312
1313                 /*
1314                  * Recal all pools on this tick.
1315                  */
1316                 ldlm_pools_recalc(LDLM_NAMESPACE_SERVER);
1317                 ldlm_pools_recalc(LDLM_NAMESPACE_CLIENT);
1318
1319                 /*
1320                  * Wait until the next check time, or until we're
1321                  * stopped.
1322                  */
1323                 lwi = LWI_TIMEOUT(cfs_time_seconds(LDLM_POOLS_THREAD_PERIOD),
1324                                   NULL, NULL);
1325                 l_wait_event(thread->t_ctl_waitq,
1326                              thread_is_stopping(thread) ||
1327                              thread_is_event(thread),
1328                              &lwi);
1329
1330                 if (thread_test_and_clear_flags(thread, SVC_STOPPING))
1331                         break;
1332                 else
1333                         thread_test_and_clear_flags(thread, SVC_EVENT);
1334         }
1335
1336         thread_set_flags(thread, SVC_STOPPED);
1337         cfs_waitq_signal(&thread->t_ctl_waitq);
1338
1339         CDEBUG(D_DLMTRACE, "%s: pool thread exiting, process %d\n",
1340                t_name, cfs_curproc_pid());
1341
1342         cfs_complete_and_exit(&ldlm_pools_comp, 0);
1343 }
1344
1345 static int ldlm_pools_thread_start(void)
1346 {
1347         struct l_wait_info lwi = { 0 };
1348         int rc;
1349         ENTRY;
1350
1351         if (ldlm_pools_thread != NULL)
1352                 RETURN(-EALREADY);
1353
1354         OBD_ALLOC_PTR(ldlm_pools_thread);
1355         if (ldlm_pools_thread == NULL)
1356                 RETURN(-ENOMEM);
1357
1358         cfs_init_completion(&ldlm_pools_comp);
1359         cfs_waitq_init(&ldlm_pools_thread->t_ctl_waitq);
1360
1361         /*
1362          * CLONE_VM and CLONE_FILES just avoid a needless copy, because we
1363          * just drop the VM and FILES in cfs_daemonize() right away.
1364          */
1365         rc = cfs_create_thread(ldlm_pools_thread_main, ldlm_pools_thread,
1366                                CFS_DAEMON_FLAGS);
1367         if (rc < 0) {
1368                 CERROR("Can't start pool thread, error %d\n",
1369                        rc);
1370                 OBD_FREE(ldlm_pools_thread, sizeof(*ldlm_pools_thread));
1371                 ldlm_pools_thread = NULL;
1372                 RETURN(rc);
1373         }
1374         l_wait_event(ldlm_pools_thread->t_ctl_waitq,
1375                      thread_is_running(ldlm_pools_thread), &lwi);
1376         RETURN(0);
1377 }
1378
1379 static void ldlm_pools_thread_stop(void)
1380 {
1381         ENTRY;
1382
1383         if (ldlm_pools_thread == NULL) {
1384                 EXIT;
1385                 return;
1386         }
1387
1388         thread_set_flags(ldlm_pools_thread, SVC_STOPPING);
1389         cfs_waitq_signal(&ldlm_pools_thread->t_ctl_waitq);
1390
1391         /*
1392          * Make sure that pools thread is finished before freeing @thread.
1393          * This fixes possible race and oops due to accessing freed memory
1394          * in pools thread.
1395          */
1396         cfs_wait_for_completion(&ldlm_pools_comp);
1397         OBD_FREE_PTR(ldlm_pools_thread);
1398         ldlm_pools_thread = NULL;
1399         EXIT;
1400 }
1401
1402 int ldlm_pools_init(void)
1403 {
1404         int rc;
1405         ENTRY;
1406
1407         rc = ldlm_pools_thread_start();
1408         if (rc == 0) {
1409                 ldlm_pools_srv_shrinker =
1410                         cfs_set_shrinker(CFS_DEFAULT_SEEKS,
1411                                          ldlm_pools_srv_shrink);
1412                 ldlm_pools_cli_shrinker =
1413                         cfs_set_shrinker(CFS_DEFAULT_SEEKS,
1414                                          ldlm_pools_cli_shrink);
1415         }
1416         RETURN(rc);
1417 }
1418 EXPORT_SYMBOL(ldlm_pools_init);
1419
1420 void ldlm_pools_fini(void)
1421 {
1422         if (ldlm_pools_srv_shrinker != NULL) {
1423                 cfs_remove_shrinker(ldlm_pools_srv_shrinker);
1424                 ldlm_pools_srv_shrinker = NULL;
1425         }
1426         if (ldlm_pools_cli_shrinker != NULL) {
1427                 cfs_remove_shrinker(ldlm_pools_cli_shrinker);
1428                 ldlm_pools_cli_shrinker = NULL;
1429         }
1430         ldlm_pools_thread_stop();
1431 }
1432 EXPORT_SYMBOL(ldlm_pools_fini);
1433 #endif /* __KERNEL__ */
1434
1435 #else /* !HAVE_LRU_RESIZE_SUPPORT */
1436 int ldlm_pool_setup(struct ldlm_pool *pl, int limit)
1437 {
1438         return 0;
1439 }
1440 EXPORT_SYMBOL(ldlm_pool_setup);
1441
1442 int ldlm_pool_recalc(struct ldlm_pool *pl)
1443 {
1444         return 0;
1445 }
1446 EXPORT_SYMBOL(ldlm_pool_recalc);
1447
1448 int ldlm_pool_shrink(struct ldlm_pool *pl,
1449                      int nr, unsigned int gfp_mask)
1450 {
1451         return 0;
1452 }
1453 EXPORT_SYMBOL(ldlm_pool_shrink);
1454
1455 int ldlm_pool_init(struct ldlm_pool *pl, struct ldlm_namespace *ns,
1456                    int idx, ldlm_side_t client)
1457 {
1458         return 0;
1459 }
1460 EXPORT_SYMBOL(ldlm_pool_init);
1461
1462 void ldlm_pool_fini(struct ldlm_pool *pl)
1463 {
1464         return;
1465 }
1466 EXPORT_SYMBOL(ldlm_pool_fini);
1467
1468 void ldlm_pool_add(struct ldlm_pool *pl, struct ldlm_lock *lock)
1469 {
1470         return;
1471 }
1472 EXPORT_SYMBOL(ldlm_pool_add);
1473
1474 void ldlm_pool_del(struct ldlm_pool *pl, struct ldlm_lock *lock)
1475 {
1476         return;
1477 }
1478 EXPORT_SYMBOL(ldlm_pool_del);
1479
1480 __u64 ldlm_pool_get_slv(struct ldlm_pool *pl)
1481 {
1482         return 1;
1483 }
1484 EXPORT_SYMBOL(ldlm_pool_get_slv);
1485
1486 void ldlm_pool_set_slv(struct ldlm_pool *pl, __u64 slv)
1487 {
1488         return;
1489 }
1490 EXPORT_SYMBOL(ldlm_pool_set_slv);
1491
1492 __u64 ldlm_pool_get_clv(struct ldlm_pool *pl)
1493 {
1494         return 1;
1495 }
1496 EXPORT_SYMBOL(ldlm_pool_get_clv);
1497
1498 void ldlm_pool_set_clv(struct ldlm_pool *pl, __u64 clv)
1499 {
1500         return;
1501 }
1502 EXPORT_SYMBOL(ldlm_pool_set_clv);
1503
1504 __u32 ldlm_pool_get_limit(struct ldlm_pool *pl)
1505 {
1506         return 0;
1507 }
1508 EXPORT_SYMBOL(ldlm_pool_get_limit);
1509
1510 void ldlm_pool_set_limit(struct ldlm_pool *pl, __u32 limit)
1511 {
1512         return;
1513 }
1514 EXPORT_SYMBOL(ldlm_pool_set_limit);
1515
1516 __u32 ldlm_pool_get_lvf(struct ldlm_pool *pl)
1517 {
1518         return 0;
1519 }
1520 EXPORT_SYMBOL(ldlm_pool_get_lvf);
1521
1522 int ldlm_pools_init(void)
1523 {
1524         return 0;
1525 }
1526 EXPORT_SYMBOL(ldlm_pools_init);
1527
1528 void ldlm_pools_fini(void)
1529 {
1530         return;
1531 }
1532 EXPORT_SYMBOL(ldlm_pools_fini);
1533
1534 void ldlm_pools_recalc(ldlm_side_t client)
1535 {
1536         return;
1537 }
1538 EXPORT_SYMBOL(ldlm_pools_recalc);
1539 #endif /* HAVE_LRU_RESIZE_SUPPORT */