2 * Copyright (C) 2012 Cray, Inc.
4 * Author: Nic Henke <nic@cray.com>
5 * Author: James Shimek <jshimek@cray.com>
7 * This file is part of Lustre, http://www.lustre.org.
9 * Lustre is free software; you can redistribute it and/or
10 * modify it under the terms of version 2 of the GNU General Public
11 * License as published by the Free Software Foundation.
13 * Lustre is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with Lustre; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 /* this code liberated and modified from Lustre */
25 #define DEBUG_SUBSYSTEM S_LND
29 typedef struct kgn_sysctl_data {
30 int ksd_pause_trigger;
32 int ksd_rdmaq_override;
35 static kgn_sysctl_data_t kgnilnd_sysctl;
37 #if defined(CONFIG_SYSCTL)
39 static cfs_sysctl_table_header_t *kgnilnd_table_header = NULL;
40 #ifndef HAVE_SYSCTL_UNNUMBERED
47 GNILND_RDMAQ_OVERRIDE,
50 #define GNILND_VERSION CTL_UNNUMBERED
51 #define GNILND_THREAD_PAUSE CTL_UNNUMBERED
52 #define GNILND_HW_QUIESCE CTL_UNNUMBERED
53 #define GNILND_STACK_RESET CTL_UNNUMBERED
54 #define GNILND_RDMAQ_OVERRIDE CTL_UNNUMBERED
57 static int LL_PROC_PROTO(proc_toggle_thread_pause)
59 int old_val = kgnilnd_sysctl.ksd_pause_trigger;
63 rc = ll_proc_dointvec(table, write, filp, buffer, lenp, ppos);
69 if (kgnilnd_data.kgn_init != GNILND_INIT_ALL) {
74 if (old_val != kgnilnd_sysctl.ksd_pause_trigger) {
75 down(&kgnilnd_data.kgn_quiesce_sem);
76 CDEBUG(D_NET, "setting quiesce_trigger %d\n", old_val);
77 kgnilnd_data.kgn_quiesce_trigger = kgnilnd_sysctl.ksd_pause_trigger;
78 kgnilnd_quiesce_wait("admin sysctl");
79 up(&kgnilnd_data.kgn_quiesce_sem);
85 static int LL_PROC_PROTO(proc_hw_quiesce)
91 rc = ll_proc_dointvec(table, write, filp, buffer, lenp, ppos);
97 if (kgnilnd_data.kgn_init != GNILND_INIT_ALL) {
103 /* only device 0 gets the handle, see kgnilnd_dev_init */
104 dev = &kgnilnd_data.kgn_devices[0];
106 LASSERTF(dev != NULL, "dev 0 is NULL\n");
108 kgnilnd_quiesce_end_callback(dev->gnd_handle,
109 kgnilnd_sysctl.ksd_quiesce_secs * MSEC_PER_SEC);
114 int LL_PROC_PROTO(proc_trigger_stack_reset)
123 rc = ll_proc_dointvec(table, write, filp, buffer, lenp, ppos);
127 /* only device 0 gets the handle, see kgnilnd_dev_init */
128 dev = &kgnilnd_data.kgn_devices[0];
130 LASSERTF(dev != NULL, "dev 0 is NULL\n");
132 kgnilnd_critical_error(dev->gnd_err_handle);
134 /* Wait for the reset to complete. This prevents any races in testing
135 * where we'd immediately try to send traffic again */
136 while (kgnilnd_data.kgn_needs_reset != 0) {
138 LCONSOLE((((i) & (-i)) == i) ? D_WARNING : D_NET,
139 "Waiting for stack reset request to clear\n");
140 cfs_pause(cfs_time_seconds(1 * i));
146 static int LL_PROC_PROTO(proc_toggle_rdmaq_override)
148 int old_val = kgnilnd_sysctl.ksd_rdmaq_override;
152 rc = ll_proc_dointvec(table, write, filp, buffer, lenp, ppos);
158 if (kgnilnd_data.kgn_init != GNILND_INIT_ALL) {
163 if (old_val != kgnilnd_sysctl.ksd_rdmaq_override) {
164 long new_mb = kgnilnd_sysctl.ksd_rdmaq_override * (long)(1024*1024);
165 LCONSOLE_INFO("changing RDMAQ override to %d mbytes/sec\n",
166 kgnilnd_sysctl.ksd_rdmaq_override);
167 /* override proc is mbytes, but we calc in bytes */
168 kgnilnd_data.kgn_rdmaq_override = new_mb;
175 static cfs_sysctl_table_t kgnilnd_table[] = {
177 * NB No .strategy entries have been provided since sysctl(8) prefers
178 * to go via /proc for portability.
181 INIT_CTL_NAME(GNILND_VERSION)
182 .procname = "version",
183 .data = KGNILND_BUILD_REV,
184 .maxlen = sizeof(KGNILND_BUILD_REV),
186 .proc_handler = &proc_dostring
189 INIT_CTL_NAME(GNILND_THREAD_PAUSE)
190 .procname = "thread_pause",
191 .data = &kgnilnd_sysctl.ksd_pause_trigger,
192 .maxlen = sizeof(int),
194 .proc_handler = &proc_toggle_thread_pause,
197 INIT_CTL_NAME(GNILND_HW_QUIESCE)
198 .procname = "hw_quiesce",
199 .data = &kgnilnd_sysctl.ksd_quiesce_secs,
200 .maxlen = sizeof(__u32),
202 .proc_handler = &proc_hw_quiesce,
205 INIT_CTL_NAME(GNILND_STACK_RESET)
206 .procname = "stack_reset",
208 .maxlen = sizeof(int),
210 .proc_handler = &proc_trigger_stack_reset,
213 INIT_CTL_NAME(GNILND_RDMAQ_OVERRIDE)
214 .procname = "rdmaq_override",
215 .data = &kgnilnd_sysctl.ksd_rdmaq_override,
216 .maxlen = sizeof(int),
218 .proc_handler = &proc_toggle_rdmaq_override,
223 static cfs_sysctl_table_t kgnilnd_top_table[2] = {
225 INIT_CTL_NAME(CTL_GNILND)
226 .procname = "kgnilnd",
230 .child = kgnilnd_table
235 void kgnilnd_insert_sysctl(void)
237 if (kgnilnd_table_header == NULL)
238 kgnilnd_table_header = cfs_register_sysctl_table(kgnilnd_top_table, 0);
241 void kgnilnd_remove_sysctl(void)
243 if (kgnilnd_table_header != NULL)
244 cfs_unregister_sysctl_table(kgnilnd_table_header);
246 kgnilnd_table_header = NULL;
250 void kgnilnd_insert_sysctl(void) {}
251 void kgnilnd_remove_sysctl(void) {}