Commit | Line | Data |
---|---|---|
d7e09d03 PT |
1 | /* |
2 | * GPL HEADER START | |
3 | * | |
4 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License version 2 only, | |
8 | * as published by the Free Software Foundation. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, but | |
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | * General Public License version 2 for more details (a copy is included | |
14 | * in the LICENSE file that accompanied this code). | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License | |
17 | * version 2 along with this program; If not, see | |
18 | * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf | |
19 | * | |
20 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
21 | * CA 95054 USA or visit www.sun.com if you need additional information or | |
22 | * have any questions. | |
23 | * | |
24 | * GPL HEADER END | |
25 | */ | |
26 | /* | |
27 | * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. | |
28 | * Use is subject to license terms. | |
29 | * | |
30 | * Copyright (c) 2011, Intel Corporation. | |
31 | */ | |
32 | /* | |
33 | * This file is part of Lustre, http://www.lustre.org/ | |
34 | * Lustre is a trademark of Sun Microsystems, Inc. | |
35 | */ | |
36 | ||
37 | #include <linux/module.h> | |
38 | #include <linux/sysctl.h> | |
39 | #include <linux/sched.h> | |
40 | #include <linux/mm.h> | |
d7e09d03 PT |
41 | #include <linux/slab.h> |
42 | #include <linux/stat.h> | |
43 | #include <linux/ctype.h> | |
87822e41 AS |
44 | #include <linux/bitops.h> |
45 | #include <linux/uaccess.h> | |
d7e09d03 PT |
46 | #include <linux/utsname.h> |
47 | ||
48 | #define DEBUG_SUBSYSTEM S_CLASS | |
49 | ||
610f7377 GKH |
50 | #include "../../include/obd_support.h" |
51 | #include "../../include/lprocfs_status.h" | |
d7e09d03 PT |
52 | |
53 | #ifdef CONFIG_SYSCTL | |
71b1fd9c | 54 | static struct ctl_table_header *obd_table_header; |
d7e09d03 PT |
55 | #endif |
56 | ||
e2424a12 OD |
57 | struct static_lustre_uintvalue_attr { |
58 | struct { | |
59 | struct attribute attr; | |
60 | ssize_t (*show)(struct kobject *kobj, struct attribute *attr, | |
61 | char *buf); | |
62 | ssize_t (*store)(struct kobject *kobj, struct attribute *attr, | |
63 | const char *buf, size_t len); | |
64 | } u; | |
65 | int *value; | |
66 | }; | |
67 | ||
68 | static ssize_t static_uintvalue_show(struct kobject *kobj, | |
69 | struct attribute *attr, | |
70 | char *buf) | |
d7e09d03 | 71 | { |
e2424a12 OD |
72 | struct static_lustre_uintvalue_attr *lattr = (void *)attr; |
73 | ||
74 | return sprintf(buf, "%d\n", *lattr->value); | |
75 | } | |
76 | ||
77 | static ssize_t static_uintvalue_store(struct kobject *kobj, | |
78 | struct attribute *attr, | |
79 | const char *buffer, size_t count) | |
80 | { | |
81 | struct static_lustre_uintvalue_attr *lattr = (void *)attr; | |
d7e09d03 | 82 | int rc; |
e2424a12 | 83 | unsigned int val; |
d7e09d03 | 84 | |
e2424a12 OD |
85 | rc = kstrtouint(buffer, 10, &val); |
86 | if (rc) | |
87 | return rc; | |
88 | ||
89 | *lattr->value = val; | |
90 | ||
91 | return count; | |
d7e09d03 PT |
92 | } |
93 | ||
e2424a12 OD |
94 | #define LUSTRE_STATIC_UINT_ATTR(name, value) \ |
95 | static struct static_lustre_uintvalue_attr lustre_sattr_##name = \ | |
96 | {__ATTR(name, 0644, \ | |
97 | static_uintvalue_show, \ | |
98 | static_uintvalue_store),\ | |
99 | value } | |
100 | ||
101 | LUSTRE_STATIC_UINT_ATTR(timeout, &obd_timeout); | |
102 | ||
103 | #ifdef CONFIG_SYSCTL | |
71b1fd9c | 104 | static int proc_max_dirty_pages_in_mb(struct ctl_table *table, int write, |
3bdb7ce4 | 105 | void __user *buffer, size_t *lenp, loff_t *ppos) |
d7e09d03 PT |
106 | { |
107 | int rc = 0; | |
d7e09d03 PT |
108 | |
109 | if (!table->data || !table->maxlen || !*lenp || (*ppos && !write)) { | |
110 | *lenp = 0; | |
111 | return 0; | |
112 | } | |
113 | if (write) { | |
114 | rc = lprocfs_write_frac_helper(buffer, *lenp, | |
260cdf5d | 115 | (unsigned int *)table->data, |
d7e09d03 PT |
116 | 1 << (20 - PAGE_CACHE_SHIFT)); |
117 | /* Don't allow them to let dirty pages exceed 90% of system | |
118 | * memory and set a hard minimum of 4MB. */ | |
4f6cc9ab | 119 | if (obd_max_dirty_pages > ((totalram_pages / 10) * 9)) { |
2d00bd17 JP |
120 | CERROR("Refusing to set max dirty pages to %u, which is more than 90%% of available RAM; setting to %lu\n", |
121 | obd_max_dirty_pages, | |
4f6cc9ab | 122 | ((totalram_pages / 10) * 9)); |
b6ee3824 | 123 | obd_max_dirty_pages = (totalram_pages / 10) * 9; |
d7e09d03 PT |
124 | } else if (obd_max_dirty_pages < 4 << (20 - PAGE_CACHE_SHIFT)) { |
125 | obd_max_dirty_pages = 4 << (20 - PAGE_CACHE_SHIFT); | |
126 | } | |
127 | } else { | |
128 | char buf[21]; | |
129 | int len; | |
130 | ||
131 | len = lprocfs_read_frac_helper(buf, sizeof(buf), | |
260cdf5d | 132 | *(unsigned int *)table->data, |
d7e09d03 PT |
133 | 1 << (20 - PAGE_CACHE_SHIFT)); |
134 | if (len > *lenp) | |
135 | len = *lenp; | |
136 | buf[len] = '\0'; | |
137 | if (copy_to_user(buffer, buf, len)) | |
138 | return -EFAULT; | |
139 | *lenp = len; | |
140 | } | |
141 | *ppos += *lenp; | |
142 | return rc; | |
143 | } | |
144 | ||
691bc0eb | 145 | static struct ctl_table obd_table[] = { |
d7e09d03 | 146 | { |
d7e09d03 PT |
147 | .procname = "debug_peer_on_timeout", |
148 | .data = &obd_debug_peer_on_timeout, | |
149 | .maxlen = sizeof(int), | |
150 | .mode = 0644, | |
151 | .proc_handler = &proc_dointvec | |
152 | }, | |
153 | { | |
d7e09d03 PT |
154 | .procname = "dump_on_timeout", |
155 | .data = &obd_dump_on_timeout, | |
156 | .maxlen = sizeof(int), | |
157 | .mode = 0644, | |
158 | .proc_handler = &proc_dointvec | |
159 | }, | |
160 | { | |
d7e09d03 PT |
161 | .procname = "dump_on_eviction", |
162 | .data = &obd_dump_on_eviction, | |
163 | .maxlen = sizeof(int), | |
164 | .mode = 0644, | |
165 | .proc_handler = &proc_dointvec | |
166 | }, | |
d7e09d03 | 167 | { |
d7e09d03 PT |
168 | .procname = "max_dirty_mb", |
169 | .data = &obd_max_dirty_pages, | |
170 | .maxlen = sizeof(int), | |
171 | .mode = 0644, | |
172 | .proc_handler = &proc_max_dirty_pages_in_mb | |
173 | }, | |
174 | { | |
d7e09d03 PT |
175 | .procname = "at_min", |
176 | .data = &at_min, | |
177 | .maxlen = sizeof(int), | |
178 | .mode = 0644, | |
1d3ade00 | 179 | .proc_handler = &proc_dointvec, |
d7e09d03 PT |
180 | }, |
181 | { | |
d7e09d03 PT |
182 | .procname = "at_max", |
183 | .data = &at_max, | |
184 | .maxlen = sizeof(int), | |
185 | .mode = 0644, | |
1d3ade00 | 186 | .proc_handler = &proc_dointvec, |
d7e09d03 PT |
187 | }, |
188 | { | |
d7e09d03 PT |
189 | .procname = "at_extra", |
190 | .data = &at_extra, | |
191 | .maxlen = sizeof(int), | |
192 | .mode = 0644, | |
1d3ade00 | 193 | .proc_handler = &proc_dointvec, |
d7e09d03 PT |
194 | }, |
195 | { | |
d7e09d03 PT |
196 | .procname = "at_early_margin", |
197 | .data = &at_early_margin, | |
198 | .maxlen = sizeof(int), | |
199 | .mode = 0644, | |
1d3ade00 | 200 | .proc_handler = &proc_dointvec, |
d7e09d03 PT |
201 | }, |
202 | { | |
d7e09d03 PT |
203 | .procname = "at_history", |
204 | .data = &at_history, | |
205 | .maxlen = sizeof(int), | |
206 | .mode = 0644, | |
1d3ade00 | 207 | .proc_handler = &proc_dointvec, |
e780e3de PT |
208 | }, |
209 | {} | |
d7e09d03 PT |
210 | }; |
211 | ||
691bc0eb | 212 | static struct ctl_table parent_table[] = { |
d7e09d03 | 213 | { |
d7e09d03 PT |
214 | .procname = "lustre", |
215 | .data = NULL, | |
216 | .maxlen = 0, | |
217 | .mode = 0555, | |
218 | .child = obd_table | |
e780e3de PT |
219 | }, |
220 | {} | |
d7e09d03 PT |
221 | }; |
222 | #endif | |
223 | ||
e2424a12 OD |
224 | static struct attribute *lustre_attrs[] = { |
225 | &lustre_sattr_timeout.u.attr, | |
226 | NULL, | |
227 | }; | |
228 | ||
229 | static struct attribute_group lustre_attr_group = { | |
230 | .attrs = lustre_attrs, | |
231 | }; | |
232 | ||
233 | int obd_sysctl_init(void) | |
d7e09d03 PT |
234 | { |
235 | #ifdef CONFIG_SYSCTL | |
e4f3771f | 236 | if (!obd_table_header) |
a7f24447 | 237 | obd_table_header = register_sysctl_table(parent_table); |
d7e09d03 | 238 | #endif |
e2424a12 | 239 | return sysfs_create_group(lustre_kobj, &lustre_attr_group); |
d7e09d03 PT |
240 | } |
241 | ||
e4f3771f | 242 | void obd_sysctl_clean(void) |
d7e09d03 PT |
243 | { |
244 | #ifdef CONFIG_SYSCTL | |
e4f3771f | 245 | if (obd_table_header) |
d7e09d03 PT |
246 | unregister_sysctl_table(obd_table_header); |
247 | obd_table_header = NULL; | |
248 | #endif | |
249 | } |