1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
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
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
29 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
30 * Use is subject to license terms.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
37 #include <linux/module.h>
38 #include <linux/autoconf.h>
39 #include <linux/sysctl.h>
40 #include <linux/sched.h>
42 #include <linux/sysctl.h>
43 #include <linux/version.h>
44 #include <linux/proc_fs.h>
45 #include <linux/slab.h>
46 #include <linux/stat.h>
47 #include <linux/ctype.h>
48 #include <asm/bitops.h>
49 #include <asm/uaccess.h>
50 #include <linux/utsname.h>
52 #define DEBUG_SUBSYSTEM S_CLASS
54 #include <obd_support.h>
55 #include <lprocfs_status.h>
58 cfs_sysctl_table_header_t *obd_table_header = NULL;
61 #ifndef HAVE_SYSCTL_UNNUMBERED
63 #define OBD_SYSCTL 300
66 OBD_TIMEOUT = 3, /* RPC timeout before recovery/intr */
67 OBD_DUMP_ON_TIMEOUT, /* dump kernel debug log upon eviction */
68 OBD_MEMUSED, /* bytes currently OBD_ALLOCated */
69 OBD_PAGESUSED, /* pages currently OBD_PAGE_ALLOCated */
70 OBD_MAXMEMUSED, /* maximum bytes OBD_ALLOCated concurrently */
71 OBD_MAXPAGESUSED, /* maximum pages OBD_PAGE_ALLOCated concurrently */
72 OBD_SYNCFILTER, /* XXX temporary, as we play with sync osts.. */
73 OBD_LDLM_TIMEOUT, /* LDLM timeout for ASTs before client eviction */
74 OBD_DUMP_ON_EVICTION, /* dump kernel debug log upon eviction */
75 OBD_DEBUG_PEER_ON_TIMEOUT, /* dump peer debug when RPC times out */
76 OBD_ALLOC_FAIL_RATE, /* memory allocation random failure rate */
77 OBD_MAX_DIRTY_PAGES, /* maximum dirty pages */
78 OBD_AT_MIN, /* Adaptive timeouts params */
87 #define OBD_SYSCTL CTL_UNNUMBERED
89 #define OBD_FAIL_LOC CTL_UNNUMBERED
90 #define OBD_FAIL_VAL CTL_UNNUMBERED
91 #define OBD_TIMEOUT CTL_UNNUMBERED
92 #define OBD_DUMP_ON_TIMEOUT CTL_UNNUMBERED
93 #define OBD_MEMUSED CTL_UNNUMBERED
94 #define OBD_PAGESUSED CTL_UNNUMBERED
95 #define OBD_MAXMEMUSED CTL_UNNUMBERED
96 #define OBD_MAXPAGESUSED CTL_UNNUMBERED
97 #define OBD_SYNCFILTER CTL_UNNUMBERED
98 #define OBD_LDLM_TIMEOUT CTL_UNNUMBERED
99 #define OBD_DUMP_ON_EVICTION CTL_UNNUMBERED
100 #define OBD_DEBUG_PEER_ON_TIMEOUT CTL_UNNUMBERED
101 #define OBD_ALLOC_FAIL_RATE CTL_UNNUMBERED
102 #define OBD_MAX_DIRTY_PAGES CTL_UNNUMBERED
103 #define OBD_AT_MIN CTL_UNNUMBERED
104 #define OBD_AT_MAX CTL_UNNUMBERED
105 #define OBD_AT_EXTRA CTL_UNNUMBERED
106 #define OBD_AT_EARLY_MARGIN CTL_UNNUMBERED
107 #define OBD_AT_HISTORY CTL_UNNUMBERED
111 int LL_PROC_PROTO(proc_set_timeout)
115 rc = ll_proc_dointvec(table, write, filp, buffer, lenp, ppos);
116 if (ldlm_timeout >= obd_timeout)
117 ldlm_timeout = max(obd_timeout / 3, 1U);
121 int LL_PROC_PROTO(proc_memory_alloc)
125 DECLARE_LL_PROC_PPOS_DECL;
127 if (!*lenp || (*ppos && !write)) {
134 len = snprintf(buf, sizeof(buf), LPU64"\n", obd_memory_sum());
138 if (cfs_copy_to_user(buffer, buf, len))
145 int LL_PROC_PROTO(proc_pages_alloc)
149 DECLARE_LL_PROC_PPOS_DECL;
151 if (!*lenp || (*ppos && !write)) {
158 len = snprintf(buf, sizeof(buf), LPU64"\n", obd_pages_sum());
162 if (cfs_copy_to_user(buffer, buf, len))
169 int LL_PROC_PROTO(proc_mem_max)
173 DECLARE_LL_PROC_PPOS_DECL;
175 if (!*lenp || (*ppos && !write)) {
182 len = snprintf(buf, sizeof(buf), LPU64"\n", obd_memory_max());
186 if (cfs_copy_to_user(buffer, buf, len))
193 int LL_PROC_PROTO(proc_pages_max)
197 DECLARE_LL_PROC_PPOS_DECL;
199 if (!*lenp || (*ppos && !write)) {
206 len = snprintf(buf, sizeof(buf), LPU64"\n", obd_pages_max());
210 if (cfs_copy_to_user(buffer, buf, len))
217 int LL_PROC_PROTO(proc_max_dirty_pages_in_mb)
220 DECLARE_LL_PROC_PPOS_DECL;
222 if (!table->data || !table->maxlen || !*lenp || (*ppos && !write)) {
227 rc = lprocfs_write_frac_helper(buffer, *lenp,
228 (unsigned int*)table->data,
229 1 << (20 - CFS_PAGE_SHIFT));
230 /* Don't allow them to let dirty pages exceed 90% of system
231 * memory and set a hard minimum of 4MB. */
232 if (obd_max_dirty_pages > ((cfs_num_physpages / 10) * 9)) {
233 CERROR("Refusing to set max dirty pages to %u, which "
234 "is more than 90%% of available RAM; setting "
235 "to %lu\n", obd_max_dirty_pages,
236 ((cfs_num_physpages / 10) * 9));
237 obd_max_dirty_pages = ((cfs_num_physpages / 10) * 9);
238 } else if (obd_max_dirty_pages < 4 << (20 - CFS_PAGE_SHIFT)) {
239 obd_max_dirty_pages = 4 << (20 - CFS_PAGE_SHIFT);
245 len = lprocfs_read_frac_helper(buf, sizeof(buf),
246 *(unsigned int*)table->data,
247 1 << (20 - CFS_PAGE_SHIFT));
251 if (cfs_copy_to_user(buffer, buf, len))
259 #ifdef RANDOM_FAIL_ALLOC
260 int LL_PROC_PROTO(proc_alloc_fail_rate)
263 DECLARE_LL_PROC_PPOS_DECL;
265 if (!table->data || !table->maxlen || !*lenp || (*ppos && !write)) {
270 rc = lprocfs_write_frac_helper(buffer, *lenp,
271 (unsigned int*)table->data,
272 OBD_ALLOC_FAIL_MULT);
277 len = lprocfs_read_frac_helper(buf, 21,
278 *(unsigned int*)table->data,
279 OBD_ALLOC_FAIL_MULT);
283 if (cfs_copy_to_user(buffer, buf, len))
292 int LL_PROC_PROTO(proc_at_min)
294 return ll_proc_dointvec(table, write, filp, buffer, lenp, ppos);
296 int LL_PROC_PROTO(proc_at_max)
298 return ll_proc_dointvec(table, write, filp, buffer, lenp, ppos);
300 int LL_PROC_PROTO(proc_at_extra)
302 return ll_proc_dointvec(table, write, filp, buffer, lenp, ppos);
304 int LL_PROC_PROTO(proc_at_early_margin)
306 return ll_proc_dointvec(table, write, filp, buffer, lenp, ppos);
308 int LL_PROC_PROTO(proc_at_history)
310 return ll_proc_dointvec(table, write, filp, buffer, lenp, ppos);
314 static cfs_sysctl_table_t obd_table[] = {
316 .ctl_name = OBD_TIMEOUT,
317 .procname = "timeout",
318 .data = &obd_timeout,
319 .maxlen = sizeof(int),
321 .proc_handler = &proc_set_timeout
324 .ctl_name = OBD_DEBUG_PEER_ON_TIMEOUT,
325 .procname = "debug_peer_on_timeout",
326 .data = &obd_debug_peer_on_timeout,
327 .maxlen = sizeof(int),
329 .proc_handler = &proc_dointvec
332 .ctl_name = OBD_DUMP_ON_TIMEOUT,
333 .procname = "dump_on_timeout",
334 .data = &obd_dump_on_timeout,
335 .maxlen = sizeof(int),
337 .proc_handler = &proc_dointvec
340 .ctl_name = OBD_DUMP_ON_EVICTION,
341 .procname = "dump_on_eviction",
342 .data = &obd_dump_on_eviction,
343 .maxlen = sizeof(int),
345 .proc_handler = &proc_dointvec
348 .ctl_name = OBD_MEMUSED,
349 .procname = "memused",
353 .proc_handler = &proc_memory_alloc
356 .ctl_name = OBD_PAGESUSED,
357 .procname = "pagesused",
361 .proc_handler = &proc_pages_alloc
364 .ctl_name = OBD_MAXMEMUSED,
365 .procname = "memused_max",
369 .proc_handler = &proc_mem_max
372 .ctl_name = OBD_MAXPAGESUSED,
373 .procname = "pagesused_max",
377 .proc_handler = &proc_pages_max
380 .ctl_name = OBD_LDLM_TIMEOUT,
381 .procname = "ldlm_timeout",
382 .data = &ldlm_timeout,
383 .maxlen = sizeof(int),
385 .proc_handler = &proc_set_timeout
387 #ifdef RANDOM_FAIL_ALLOC
389 .ctl_name = OBD_ALLOC_FAIL_RATE,
390 .procname = "alloc_fail_rate",
391 .data = &obd_alloc_fail_rate,
392 .maxlen = sizeof(int),
394 .proc_handler = &proc_alloc_fail_rate
398 .ctl_name = OBD_MAX_DIRTY_PAGES,
399 .procname = "max_dirty_mb",
400 .data = &obd_max_dirty_pages,
401 .maxlen = sizeof(int),
403 .proc_handler = &proc_max_dirty_pages_in_mb
406 .ctl_name = OBD_AT_MIN,
407 .procname = "at_min",
409 .maxlen = sizeof(int),
411 .proc_handler = &proc_at_min
414 .ctl_name = OBD_AT_MAX,
415 .procname = "at_max",
417 .maxlen = sizeof(int),
419 .proc_handler = &proc_at_max
422 .ctl_name = OBD_AT_EXTRA,
423 .procname = "at_extra",
425 .maxlen = sizeof(int),
427 .proc_handler = &proc_at_extra
430 .ctl_name = OBD_AT_EARLY_MARGIN,
431 .procname = "at_early_margin",
432 .data = &at_early_margin,
433 .maxlen = sizeof(int),
435 .proc_handler = &proc_at_early_margin
438 .ctl_name = OBD_AT_HISTORY,
439 .procname = "at_history",
441 .maxlen = sizeof(int),
443 .proc_handler = &proc_at_history
448 static cfs_sysctl_table_t parent_table[] = {
450 .ctl_name = OBD_SYSCTL,
451 .procname = "lustre",
461 void obd_sysctl_init (void)
464 if ( !obd_table_header )
465 obd_table_header = cfs_register_sysctl_table(parent_table, 0);
469 void obd_sysctl_clean (void)
472 if ( obd_table_header )
473 cfs_unregister_sysctl_table(obd_table_header);
474 obd_table_header = NULL;