staging/lustre/obdclass: move debug controls to sysfs
[linux-2.6-block.git] / drivers / staging / lustre / lustre / obdclass / linux / linux-sysctl.c
CommitLineData
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 54static struct ctl_table_header *obd_table_header;
d7e09d03
PT
55#endif
56
e2424a12
OD
57struct 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
68static 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
77static 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) \
95static struct static_lustre_uintvalue_attr lustre_sattr_##name = \
96 {__ATTR(name, 0644, \
97 static_uintvalue_show, \
98 static_uintvalue_store),\
99 value }
100
101LUSTRE_STATIC_UINT_ATTR(timeout, &obd_timeout);
102
df476a4d
OD
103static ssize_t max_dirty_mb_show(struct kobject *kobj, struct attribute *attr,
104 char *buf)
d7e09d03 105{
df476a4d
OD
106 return sprintf(buf, "%ul\n",
107 obd_max_dirty_pages / (1 << (20 - PAGE_CACHE_SHIFT)));
108}
109
110static ssize_t max_dirty_mb_store(struct kobject *kobj, struct attribute *attr,
111 const char *buffer, size_t count)
112{
113 int rc;
114 unsigned long val;
115
116 rc = kstrtoul(buffer, 10, &val);
117 if (rc)
118 return rc;
119
120 val *= 1 << (20 - PAGE_CACHE_SHIFT); /* convert to pages */
d7e09d03 121
df476a4d
OD
122 if (val > ((totalram_pages / 10) * 9)) {
123 /* Somebody wants to assign too much memory to dirty pages */
124 return -EINVAL;
d7e09d03 125 }
df476a4d
OD
126
127 if (val < 4 << (20 - PAGE_CACHE_SHIFT)) {
128 /* Less than 4 Mb for dirty cache is also bad */
129 return -EINVAL;
d7e09d03 130 }
df476a4d
OD
131
132 obd_max_dirty_pages = val;
133
134 return count;
d7e09d03 135}
df476a4d 136LUSTRE_RW_ATTR(max_dirty_mb);
d7e09d03 137
9e7fa149
OD
138LUSTRE_STATIC_UINT_ATTR(debug_peer_on_timeout, &obd_debug_peer_on_timeout);
139LUSTRE_STATIC_UINT_ATTR(dump_on_timeout, &obd_dump_on_timeout);
140LUSTRE_STATIC_UINT_ATTR(dump_on_eviction, &obd_dump_on_eviction);
141
df476a4d 142#ifdef CONFIG_SYSCTL
691bc0eb 143static struct ctl_table obd_table[] = {
d7e09d03 144 {
d7e09d03
PT
145 .procname = "at_min",
146 .data = &at_min,
147 .maxlen = sizeof(int),
148 .mode = 0644,
1d3ade00 149 .proc_handler = &proc_dointvec,
d7e09d03
PT
150 },
151 {
d7e09d03
PT
152 .procname = "at_max",
153 .data = &at_max,
154 .maxlen = sizeof(int),
155 .mode = 0644,
1d3ade00 156 .proc_handler = &proc_dointvec,
d7e09d03
PT
157 },
158 {
d7e09d03
PT
159 .procname = "at_extra",
160 .data = &at_extra,
161 .maxlen = sizeof(int),
162 .mode = 0644,
1d3ade00 163 .proc_handler = &proc_dointvec,
d7e09d03
PT
164 },
165 {
d7e09d03
PT
166 .procname = "at_early_margin",
167 .data = &at_early_margin,
168 .maxlen = sizeof(int),
169 .mode = 0644,
1d3ade00 170 .proc_handler = &proc_dointvec,
d7e09d03
PT
171 },
172 {
d7e09d03
PT
173 .procname = "at_history",
174 .data = &at_history,
175 .maxlen = sizeof(int),
176 .mode = 0644,
1d3ade00 177 .proc_handler = &proc_dointvec,
e780e3de
PT
178 },
179 {}
d7e09d03
PT
180};
181
691bc0eb 182static struct ctl_table parent_table[] = {
d7e09d03 183 {
d7e09d03
PT
184 .procname = "lustre",
185 .data = NULL,
186 .maxlen = 0,
187 .mode = 0555,
188 .child = obd_table
e780e3de
PT
189 },
190 {}
d7e09d03
PT
191};
192#endif
193
e2424a12
OD
194static struct attribute *lustre_attrs[] = {
195 &lustre_sattr_timeout.u.attr,
df476a4d 196 &lustre_attr_max_dirty_mb.attr,
9e7fa149
OD
197 &lustre_sattr_debug_peer_on_timeout.u.attr,
198 &lustre_sattr_dump_on_timeout.u.attr,
199 &lustre_sattr_dump_on_eviction.u.attr,
e2424a12
OD
200 NULL,
201};
202
203static struct attribute_group lustre_attr_group = {
204 .attrs = lustre_attrs,
205};
206
207int obd_sysctl_init(void)
d7e09d03
PT
208{
209#ifdef CONFIG_SYSCTL
e4f3771f 210 if (!obd_table_header)
a7f24447 211 obd_table_header = register_sysctl_table(parent_table);
d7e09d03 212#endif
e2424a12 213 return sysfs_create_group(lustre_kobj, &lustre_attr_group);
d7e09d03
PT
214}
215
e4f3771f 216void obd_sysctl_clean(void)
d7e09d03
PT
217{
218#ifdef CONFIG_SYSCTL
e4f3771f 219 if (obd_table_header)
d7e09d03
PT
220 unregister_sysctl_table(obd_table_header);
221 obd_table_header = NULL;
222#endif
223}