1
/*****************************************************************************\
2
* Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
3
* Copyright (C) 2007 The Regents of the University of California.
4
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
5
* Written by Brian Behlendorf <behlendorf1@llnl.gov>.
8
* This file is part of the SPL, Solaris Porting Layer.
9
* For details, see <http://zfsonlinux.org/>.
11
* The SPL is free software; you can redistribute it and/or modify it
12
* under the terms of the GNU General Public License as published by the
13
* Free Software Foundation; either version 2 of the License, or (at your
14
* option) any later version.
16
* The SPL is distributed in the hope that it will be useful, but WITHOUT
17
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21
* You should have received a copy of the GNU General Public License along
22
* with the SPL. If not, see <http://www.gnu.org/licenses/>.
23
*****************************************************************************
24
* Solaris Porting Layer (SPL) Proc Implementation.
25
\*****************************************************************************/
27
#include <sys/systeminfo.h>
28
#include <sys/kstat.h>
29
#include <linux/kmod.h>
30
#include <linux/seq_file.h>
31
#include <linux/proc_compat.h>
32
#include <spl-debug.h>
34
#ifdef SS_DEBUG_SUBSYS
35
#undef SS_DEBUG_SUBSYS
38
#define SS_DEBUG_SUBSYS SS_PROC
41
static unsigned long table_min = 0;
42
static unsigned long table_max = ~0;
46
static struct ctl_table_header *spl_header = NULL;
47
#endif /* CONFIG_SYSCTL */
49
static struct proc_dir_entry *proc_spl = NULL;
51
static struct proc_dir_entry *proc_spl_kmem = NULL;
52
static struct proc_dir_entry *proc_spl_kmem_slab = NULL;
53
#endif /* DEBUG_KMEM */
54
struct proc_dir_entry *proc_spl_kstat = NULL;
57
#ifdef HAVE_CTL_UNNUMBERED
59
#define CTL_SPL CTL_UNNUMBERED
60
#define CTL_SPL_DEBUG CTL_UNNUMBERED
61
#define CTL_SPL_VM CTL_UNNUMBERED
62
#define CTL_SPL_MUTEX CTL_UNNUMBERED
63
#define CTL_SPL_KMEM CTL_UNNUMBERED
64
#define CTL_SPL_KSTAT CTL_UNNUMBERED
66
#define CTL_VERSION CTL_UNNUMBERED /* Version */
67
#define CTL_HOSTID CTL_UNNUMBERED /* Host id by /usr/bin/hostid */
68
#define CTL_HW_SERIAL CTL_UNNUMBERED /* HW serial number by hostid */
69
#define CTL_KALLSYMS CTL_UNNUMBERED /* kallsyms_lookup_name addr */
71
#define CTL_DEBUG_SUBSYS CTL_UNNUMBERED /* Debug subsystem */
72
#define CTL_DEBUG_MASK CTL_UNNUMBERED /* Debug mask */
73
#define CTL_DEBUG_PRINTK CTL_UNNUMBERED /* All messages to console */
74
#define CTL_DEBUG_MB CTL_UNNUMBERED /* Debug buffer size */
75
#define CTL_DEBUG_BINARY CTL_UNNUMBERED /* Binary data in buffer */
76
#define CTL_DEBUG_CATASTROPHE CTL_UNNUMBERED /* Set if BUG'd or panic'd */
77
#define CTL_DEBUG_PANIC_ON_BUG CTL_UNNUMBERED /* Should panic on BUG */
78
#define CTL_DEBUG_PATH CTL_UNNUMBERED /* Dump log location */
79
#define CTL_DEBUG_DUMP CTL_UNNUMBERED /* Dump debug buffer to file */
80
#define CTL_DEBUG_FORCE_BUG CTL_UNNUMBERED /* Hook to force a BUG */
81
#define CTL_DEBUG_STACK_SIZE CTL_UNNUMBERED /* Max observed stack size */
83
#define CTL_CONSOLE_RATELIMIT CTL_UNNUMBERED /* Ratelimit console messages */
84
#define CTL_CONSOLE_MAX_DELAY_CS CTL_UNNUMBERED /* Max delay skip messages */
85
#define CTL_CONSOLE_MIN_DELAY_CS CTL_UNNUMBERED /* Init delay skip messages */
86
#define CTL_CONSOLE_BACKOFF CTL_UNNUMBERED /* Delay increase factor */
88
#define CTL_VM_MINFREE CTL_UNNUMBERED /* Minimum free memory */
89
#define CTL_VM_DESFREE CTL_UNNUMBERED /* Desired free memory */
90
#define CTL_VM_LOTSFREE CTL_UNNUMBERED /* Lots of free memory */
91
#define CTL_VM_NEEDFREE CTL_UNNUMBERED /* Need free memory */
92
#define CTL_VM_SWAPFS_MINFREE CTL_UNNUMBERED /* Minimum swapfs memory */
93
#define CTL_VM_SWAPFS_RESERVE CTL_UNNUMBERED /* Reserved swapfs memory */
94
#define CTL_VM_AVAILRMEM CTL_UNNUMBERED /* Easily available memory */
95
#define CTL_VM_FREEMEM CTL_UNNUMBERED /* Free memory */
96
#define CTL_VM_PHYSMEM CTL_UNNUMBERED /* Total physical memory */
99
#define CTL_KMEM_KMEMUSED CTL_UNNUMBERED /* Alloc'd kmem bytes */
100
#define CTL_KMEM_KMEMMAX CTL_UNNUMBERED /* Max alloc'd by kmem bytes */
101
#define CTL_KMEM_VMEMUSED CTL_UNNUMBERED /* Alloc'd vmem bytes */
102
#define CTL_KMEM_VMEMMAX CTL_UNNUMBERED /* Max alloc'd by vmem bytes */
103
#define CTL_KMEM_SLAB_KMEMTOTAL CTL_UNNUMBERED /* Total kmem slab size */
104
#define CTL_KMEM_SLAB_KMEMALLOC CTL_UNNUMBERED /* Alloc'd kmem slab size */
105
#define CTL_KMEM_SLAB_KMEMMAX CTL_UNNUMBERED /* Max kmem slab size */
106
#define CTL_KMEM_SLAB_VMEMTOTAL CTL_UNNUMBERED /* Total vmem slab size */
107
#define CTL_KMEM_SLAB_VMEMALLOC CTL_UNNUMBERED /* Alloc'd vmem slab size */
108
#define CTL_KMEM_SLAB_VMEMMAX CTL_UNNUMBERED /* Max vmem slab size */
111
#else /* HAVE_CTL_UNNUMBERED */
115
CTL_SPL_DEBUG = 0x88,
117
CTL_SPL_MUTEX = 0x90,
119
CTL_SPL_KSTAT = 0x92,
123
CTL_VERSION = 1, /* Version */
124
CTL_HOSTID, /* Host id reported by /usr/bin/hostid */
125
CTL_HW_SERIAL, /* Hardware serial number from hostid */
126
CTL_KALLSYMS, /* Address of kallsyms_lookup_name */
129
CTL_DEBUG_SUBSYS, /* Debug subsystem */
130
CTL_DEBUG_MASK, /* Debug mask */
131
CTL_DEBUG_PRINTK, /* Force all messages to console */
132
CTL_DEBUG_MB, /* Debug buffer size */
133
CTL_DEBUG_BINARY, /* Include binary data in buffer */
134
CTL_DEBUG_CATASTROPHE, /* Set if we have BUG'd or panic'd */
135
CTL_DEBUG_PANIC_ON_BUG, /* Set if we should panic on BUG */
136
CTL_DEBUG_PATH, /* Dump log location */
137
CTL_DEBUG_DUMP, /* Dump debug buffer to file */
138
CTL_DEBUG_FORCE_BUG, /* Hook to force a BUG */
139
CTL_DEBUG_STACK_SIZE, /* Max observed stack size */
142
CTL_CONSOLE_RATELIMIT, /* Ratelimit console messages */
143
CTL_CONSOLE_MAX_DELAY_CS, /* Max delay which we skip messages */
144
CTL_CONSOLE_MIN_DELAY_CS, /* Init delay which we skip messages */
145
CTL_CONSOLE_BACKOFF, /* Delay increase factor */
147
CTL_VM_MINFREE, /* Minimum free memory threshold */
148
CTL_VM_DESFREE, /* Desired free memory threshold */
149
CTL_VM_LOTSFREE, /* Lots of free memory threshold */
150
CTL_VM_NEEDFREE, /* Need free memory deficit */
151
CTL_VM_SWAPFS_MINFREE, /* Minimum swapfs memory */
152
CTL_VM_SWAPFS_RESERVE, /* Reserved swapfs memory */
153
CTL_VM_AVAILRMEM, /* Easily available memory */
154
CTL_VM_FREEMEM, /* Free memory */
155
CTL_VM_PHYSMEM, /* Total physical memory */
158
CTL_KMEM_KMEMUSED, /* Alloc'd kmem bytes */
159
CTL_KMEM_KMEMMAX, /* Max alloc'd by kmem bytes */
160
CTL_KMEM_VMEMUSED, /* Alloc'd vmem bytes */
161
CTL_KMEM_VMEMMAX, /* Max alloc'd by vmem bytes */
162
CTL_KMEM_SLAB_KMEMTOTAL, /* Total kmem slab size */
163
CTL_KMEM_SLAB_KMEMALLOC, /* Alloc'd kmem slab size */
164
CTL_KMEM_SLAB_KMEMMAX, /* Max kmem slab size */
165
CTL_KMEM_SLAB_VMEMTOTAL, /* Total vmem slab size */
166
CTL_KMEM_SLAB_VMEMALLOC, /* Alloc'd vmem slab size */
167
CTL_KMEM_SLAB_VMEMMAX, /* Max vmem slab size */
170
#endif /* HAVE_CTL_UNNUMBERED */
171
#endif /* HAVE_CTL_NAME */
174
proc_copyin_string(char *kbuffer, int kbuffer_size,
175
const char *ubuffer, int ubuffer_size)
179
if (ubuffer_size > kbuffer_size)
182
if (copy_from_user((void *)kbuffer, (void *)ubuffer, ubuffer_size))
185
/* strip trailing whitespace */
186
size = strnlen(kbuffer, ubuffer_size);
188
if (!isspace(kbuffer[size]))
195
/* no space to terminate */
196
if (size == kbuffer_size)
199
kbuffer[size + 1] = 0;
204
proc_copyout_string(char *ubuffer, int ubuffer_size,
205
const char *kbuffer, char *append)
207
/* NB if 'append' != NULL, it's a single character to append to the
208
* copied out string - usually "\n", for /proc entries and
209
* (i.e. a terminating zero byte) for sysctl entries
211
int size = MIN(strlen(kbuffer), ubuffer_size);
213
if (copy_to_user(ubuffer, kbuffer, size))
216
if (append != NULL && size < ubuffer_size) {
217
if (copy_to_user(ubuffer + size, append, 1))
227
SPL_PROC_HANDLER(proc_dobitmasks)
229
unsigned long *mask = table->data;
230
int is_subsys = (mask == &spl_debug_subsys) ? 1 : 0;
231
int is_printk = (mask == &spl_debug_printk) ? 1 : 0;
236
str = kmem_alloc(size, KM_SLEEP);
241
rc = proc_copyin_string(str, size, buffer, *lenp);
245
rc = spl_debug_str2mask(mask, str, is_subsys);
246
/* Always print BUG/ASSERT to console, so keep this mask */
252
rc = spl_debug_mask2str(str, size, *mask, is_subsys);
256
rc = proc_copyout_string(buffer, *lenp,
264
kmem_free(str, size);
268
SPL_PROC_HANDLER(proc_debug_mb)
275
rc = proc_copyin_string(str, sizeof(str), buffer, *lenp);
279
rc = spl_debug_set_mb(simple_strtoul(str, NULL, 0));
282
len = snprintf(str, sizeof(str), "%d", spl_debug_get_mb());
286
rc = proc_copyout_string(buffer,*lenp,str+*ppos,"\n");
297
SPL_PROC_HANDLER(proc_dump_kernel)
302
spl_debug_dumplog(0);
311
SPL_PROC_HANDLER(proc_force_bug)
316
PANIC("Crashing due to forced panic\n");
323
SPL_PROC_HANDLER(proc_console_max_delay_cs)
325
int rc, max_delay_cs;
326
struct ctl_table dummy = *table;
330
dummy.data = &max_delay_cs;
331
dummy.proc_handler = &proc_dointvec;
335
rc = spl_proc_dointvec(&dummy,write,filp,buffer,lenp,ppos);
339
if (max_delay_cs <= 0)
342
d = (max_delay_cs * HZ) / 100;
343
if (d == 0 || d < spl_console_min_delay)
346
spl_console_max_delay = d;
348
max_delay_cs = (spl_console_max_delay * 100) / HZ;
349
rc = spl_proc_dointvec(&dummy,write,filp,buffer,lenp,ppos);
355
SPL_PROC_HANDLER(proc_console_min_delay_cs)
357
int rc, min_delay_cs;
358
struct ctl_table dummy = *table;
362
dummy.data = &min_delay_cs;
363
dummy.proc_handler = &proc_dointvec;
367
rc = spl_proc_dointvec(&dummy,write,filp,buffer,lenp,ppos);
371
if (min_delay_cs <= 0)
374
d = (min_delay_cs * HZ) / 100;
375
if (d == 0 || d > spl_console_max_delay)
378
spl_console_min_delay = d;
380
min_delay_cs = (spl_console_min_delay * 100) / HZ;
381
rc = spl_proc_dointvec(&dummy,write,filp,buffer,lenp,ppos);
387
SPL_PROC_HANDLER(proc_console_backoff)
390
struct ctl_table dummy = *table;
393
dummy.data = &backoff;
394
dummy.proc_handler = &proc_dointvec;
398
rc = spl_proc_dointvec(&dummy,write,filp,buffer,lenp,ppos);
405
spl_console_backoff = backoff;
407
backoff = spl_console_backoff;
408
rc = spl_proc_dointvec(&dummy,write,filp,buffer,lenp,ppos);
413
#endif /* DEBUG_LOG */
416
SPL_PROC_HANDLER(proc_domemused)
419
unsigned long min = 0, max = ~0, val;
420
struct ctl_table dummy = *table;
424
dummy.proc_handler = &proc_dointvec;
431
# ifdef HAVE_ATOMIC64_T
432
val = atomic64_read((atomic64_t *)table->data);
434
val = atomic_read((atomic_t *)table->data);
435
# endif /* HAVE_ATOMIC64_T */
436
rc = spl_proc_doulongvec_minmax(&dummy, write, filp,
443
SPL_PROC_HANDLER(proc_doslab)
446
unsigned long min = 0, max = ~0, val = 0, mask;
447
struct ctl_table dummy = *table;
448
spl_kmem_cache_t *skc;
452
dummy.proc_handler = &proc_dointvec;
459
down_read(&spl_kmem_cache_sem);
460
mask = (unsigned long)table->data;
462
list_for_each_entry(skc, &spl_kmem_cache_list, skc_list) {
464
/* Only use slabs of the correct kmem/vmem type */
465
if (!(skc->skc_flags & mask))
468
/* Sum the specified field for selected slabs */
469
switch (mask & (KMC_TOTAL | KMC_ALLOC | KMC_MAX)) {
471
val += skc->skc_slab_size * skc->skc_slab_total;
474
val += skc->skc_obj_size * skc->skc_obj_alloc;
477
val += skc->skc_obj_size * skc->skc_obj_max;
482
up_read(&spl_kmem_cache_sem);
483
rc = spl_proc_doulongvec_minmax(&dummy, write, filp,
489
#endif /* DEBUG_KMEM */
491
SPL_PROC_HANDLER(proc_dohostid)
498
/* We can't use spl_proc_doulongvec_minmax() in the write
499
* case here because hostid while a hex value has no
500
* leading 0x which confuses the helper function. */
501
rc = proc_copyin_string(str, sizeof(str), buffer, *lenp);
505
spl_hostid = simple_strtoul(str, &end, 16);
509
(void) snprintf(hw_serial, HW_HOSTID_LEN, "%lu", spl_hostid);
510
hw_serial[HW_HOSTID_LEN - 1] = '\0';
513
len = snprintf(str, sizeof(str), "%lx", spl_hostid);
517
rc = proc_copyout_string(buffer,*lenp,str+*ppos,"\n");
528
#ifndef HAVE_KALLSYMS_LOOKUP_NAME
529
SPL_PROC_HANDLER(proc_dokallsyms_lookup_name)
536
/* This may only be set once at module load time */
537
if (spl_kallsyms_lookup_name_fn != SYMBOL_POISON)
540
/* We can't use spl_proc_doulongvec_minmax() in the write
541
* case here because the address while a hex value has no
542
* leading 0x which confuses the helper function. */
543
rc = proc_copyin_string(str, sizeof(str), buffer, *lenp);
547
spl_kallsyms_lookup_name_fn =
548
(kallsyms_lookup_name_t)simple_strtoul(str, &end, 16);
549
wake_up(&spl_kallsyms_lookup_name_waitq);
556
len = snprintf(str, sizeof(str), "%lx",
557
(unsigned long)spl_kallsyms_lookup_name_fn);
561
rc = proc_copyout_string(buffer,*lenp,str+*ppos,"\n");
571
#endif /* HAVE_KALLSYMS_LOOKUP_NAME */
573
SPL_PROC_HANDLER(proc_doavailrmem)
582
len = snprintf(str, sizeof(str), "%lu",
583
(unsigned long)availrmem);
587
rc = proc_copyout_string(buffer,*lenp,str+*ppos,"\n");
598
SPL_PROC_HANDLER(proc_dofreemem)
607
len = snprintf(str, sizeof(str), "%lu", (unsigned long)freemem);
611
rc = proc_copyout_string(buffer,*lenp,str+*ppos,"\n");
624
slab_seq_show_headers(struct seq_file *f)
627
"--------------------- cache ----------"
628
"--------------------------------------------- "
631
"--- emergency ---\n");
634
" flags size alloc slabsize objsize "
637
"dlock alloc max\n");
641
slab_seq_show(struct seq_file *f, void *p)
643
spl_kmem_cache_t *skc = p;
645
ASSERT(skc->skc_magic == SKC_MAGIC);
647
spin_lock(&skc->skc_lock);
648
seq_printf(f, "%-36s ", skc->skc_name);
649
seq_printf(f, "0x%05lx %9lu %9lu %8u %8u "
650
"%5lu %5lu %5lu %5lu %5lu %5lu %5lu %5lu %5lu\n",
651
(long unsigned)skc->skc_flags,
652
(long unsigned)(skc->skc_slab_size * skc->skc_slab_total),
653
(long unsigned)(skc->skc_obj_size * skc->skc_obj_alloc),
654
(unsigned)skc->skc_slab_size,
655
(unsigned)skc->skc_obj_size,
656
(long unsigned)skc->skc_slab_total,
657
(long unsigned)skc->skc_slab_alloc,
658
(long unsigned)skc->skc_slab_max,
659
(long unsigned)skc->skc_obj_total,
660
(long unsigned)skc->skc_obj_alloc,
661
(long unsigned)skc->skc_obj_max,
662
(long unsigned)skc->skc_obj_deadlock,
663
(long unsigned)skc->skc_obj_emergency,
664
(long unsigned)skc->skc_obj_emergency_max);
666
spin_unlock(&skc->skc_lock);
672
slab_seq_start(struct seq_file *f, loff_t *pos)
678
down_read(&spl_kmem_cache_sem);
680
slab_seq_show_headers(f);
682
p = spl_kmem_cache_list.next;
685
if (p == &spl_kmem_cache_list)
689
SRETURN(list_entry(p, spl_kmem_cache_t, skc_list));
693
slab_seq_next(struct seq_file *f, void *p, loff_t *pos)
695
spl_kmem_cache_t *skc = p;
699
SRETURN((skc->skc_list.next == &spl_kmem_cache_list) ?
700
NULL : list_entry(skc->skc_list.next,spl_kmem_cache_t,skc_list));
704
slab_seq_stop(struct seq_file *f, void *v)
706
up_read(&spl_kmem_cache_sem);
709
static struct seq_operations slab_seq_ops = {
710
.show = slab_seq_show,
711
.start = slab_seq_start,
712
.next = slab_seq_next,
713
.stop = slab_seq_stop,
717
proc_slab_open(struct inode *inode, struct file *filp)
719
return seq_open(filp, &slab_seq_ops);
722
static struct file_operations proc_slab_operations = {
723
.open = proc_slab_open,
726
.release = seq_release,
728
#endif /* DEBUG_KMEM */
731
static struct ctl_table spl_debug_table[] = {
733
CTL_NAME (CTL_DEBUG_SUBSYS)
734
.procname = "subsystem",
735
.data = &spl_debug_subsys,
736
.maxlen = sizeof(unsigned long),
738
.proc_handler = &proc_dobitmasks
741
CTL_NAME (CTL_DEBUG_MASK)
743
.data = &spl_debug_mask,
744
.maxlen = sizeof(unsigned long),
746
.proc_handler = &proc_dobitmasks
749
CTL_NAME (CTL_DEBUG_PRINTK)
750
.procname = "printk",
751
.data = &spl_debug_printk,
752
.maxlen = sizeof(unsigned long),
754
.proc_handler = &proc_dobitmasks
757
CTL_NAME (CTL_DEBUG_MB)
760
.proc_handler = &proc_debug_mb,
763
CTL_NAME (CTL_DEBUG_BINARY)
764
.procname = "binary",
765
.data = &spl_debug_binary,
766
.maxlen = sizeof(int),
768
.proc_handler = &proc_dointvec,
771
CTL_NAME (CTL_DEBUG_CATASTROPHE)
772
.procname = "catastrophe",
773
.data = &spl_debug_catastrophe,
774
.maxlen = sizeof(int),
776
.proc_handler = &proc_dointvec,
779
CTL_NAME (CTL_DEBUG_PANIC_ON_BUG)
780
.procname = "panic_on_bug",
781
.data = &spl_debug_panic_on_bug,
782
.maxlen = sizeof(int),
784
.proc_handler = &proc_dointvec
787
CTL_NAME (CTL_DEBUG_PATH)
789
.data = spl_debug_file_path,
790
.maxlen = sizeof(spl_debug_file_path),
792
.proc_handler = &proc_dostring,
795
CTL_NAME (CTL_DEBUG_DUMP)
798
.proc_handler = &proc_dump_kernel,
800
{ CTL_NAME (CTL_DEBUG_FORCE_BUG)
801
.procname = "force_bug",
803
.proc_handler = &proc_force_bug,
806
CTL_NAME (CTL_CONSOLE_RATELIMIT)
807
.procname = "console_ratelimit",
808
.data = &spl_console_ratelimit,
809
.maxlen = sizeof(int),
811
.proc_handler = &proc_dointvec,
814
CTL_NAME (CTL_CONSOLE_MAX_DELAY_CS)
815
.procname = "console_max_delay_centisecs",
816
.maxlen = sizeof(int),
818
.proc_handler = &proc_console_max_delay_cs,
821
CTL_NAME (CTL_CONSOLE_MIN_DELAY_CS)
822
.procname = "console_min_delay_centisecs",
823
.maxlen = sizeof(int),
825
.proc_handler = &proc_console_min_delay_cs,
828
CTL_NAME (CTL_CONSOLE_BACKOFF)
829
.procname = "console_backoff",
830
.maxlen = sizeof(int),
832
.proc_handler = &proc_console_backoff,
835
CTL_NAME (CTL_DEBUG_STACK_SIZE)
836
.procname = "stack_max",
837
.data = &spl_debug_stack,
838
.maxlen = sizeof(int),
840
.proc_handler = &proc_dointvec,
844
#endif /* DEBUG_LOG */
846
static struct ctl_table spl_vm_table[] = {
848
CTL_NAME (CTL_VM_MINFREE)
849
.procname = "minfree",
851
.maxlen = sizeof(int),
853
.proc_handler = &proc_dointvec,
856
CTL_NAME (CTL_VM_DESFREE)
857
.procname = "desfree",
859
.maxlen = sizeof(int),
861
.proc_handler = &proc_dointvec,
864
CTL_NAME (CTL_VM_LOTSFREE)
865
.procname = "lotsfree",
867
.maxlen = sizeof(int),
869
.proc_handler = &proc_dointvec,
872
CTL_NAME (CTL_VM_NEEDFREE)
873
.procname = "needfree",
875
.maxlen = sizeof(int),
877
.proc_handler = &proc_dointvec,
880
CTL_NAME (CTL_VM_SWAPFS_MINFREE)
881
.procname = "swapfs_minfree",
882
.data = &swapfs_minfree,
883
.maxlen = sizeof(int),
885
.proc_handler = &proc_dointvec,
888
CTL_NAME (CTL_VM_SWAPFS_RESERVE)
889
.procname = "swapfs_reserve",
890
.data = &swapfs_reserve,
891
.maxlen = sizeof(int),
893
.proc_handler = &proc_dointvec,
896
CTL_NAME (CTL_VM_AVAILRMEM)
897
.procname = "availrmem",
899
.proc_handler = &proc_doavailrmem,
902
CTL_NAME (CTL_VM_FREEMEM)
903
.procname = "freemem",
905
.maxlen = sizeof(int),
907
.proc_handler = &proc_dofreemem,
910
CTL_NAME (CTL_VM_PHYSMEM)
911
.procname = "physmem",
913
.maxlen = sizeof(int),
915
.proc_handler = &proc_dointvec,
921
static struct ctl_table spl_kmem_table[] = {
923
CTL_NAME (CTL_KMEM_KMEMUSED)
924
.procname = "kmem_used",
925
.data = &kmem_alloc_used,
926
# ifdef HAVE_ATOMIC64_T
927
.maxlen = sizeof(atomic64_t),
929
.maxlen = sizeof(atomic_t),
930
# endif /* HAVE_ATOMIC64_T */
932
.proc_handler = &proc_domemused,
935
CTL_NAME (CTL_KMEM_KMEMMAX)
936
.procname = "kmem_max",
937
.data = &kmem_alloc_max,
938
.maxlen = sizeof(unsigned long),
939
.extra1 = &table_min,
940
.extra2 = &table_max,
942
.proc_handler = &proc_doulongvec_minmax,
945
CTL_NAME (CTL_KMEM_VMEMUSED)
946
.procname = "vmem_used",
947
.data = &vmem_alloc_used,
948
# ifdef HAVE_ATOMIC64_T
949
.maxlen = sizeof(atomic64_t),
951
.maxlen = sizeof(atomic_t),
952
# endif /* HAVE_ATOMIC64_T */
954
.proc_handler = &proc_domemused,
957
CTL_NAME (CTL_KMEM_VMEMMAX)
958
.procname = "vmem_max",
959
.data = &vmem_alloc_max,
960
.maxlen = sizeof(unsigned long),
961
.extra1 = &table_min,
962
.extra2 = &table_max,
964
.proc_handler = &proc_doulongvec_minmax,
967
CTL_NAME (CTL_KMEM_SLAB_KMEMTOTAL)
968
.procname = "slab_kmem_total",
969
.data = (void *)(KMC_KMEM | KMC_TOTAL),
970
.maxlen = sizeof(unsigned long),
971
.extra1 = &table_min,
972
.extra2 = &table_max,
974
.proc_handler = &proc_doslab,
977
CTL_NAME (CTL_KMEM_SLAB_KMEMALLOC)
978
.procname = "slab_kmem_alloc",
979
.data = (void *)(KMC_KMEM | KMC_ALLOC),
980
.maxlen = sizeof(unsigned long),
981
.extra1 = &table_min,
982
.extra2 = &table_max,
984
.proc_handler = &proc_doslab,
987
CTL_NAME (CTL_KMEM_SLAB_KMEMMAX)
988
.procname = "slab_kmem_max",
989
.data = (void *)(KMC_KMEM | KMC_MAX),
990
.maxlen = sizeof(unsigned long),
991
.extra1 = &table_min,
992
.extra2 = &table_max,
994
.proc_handler = &proc_doslab,
997
CTL_NAME (CTL_KMEM_SLAB_VMEMTOTAL)
998
.procname = "slab_vmem_total",
999
.data = (void *)(KMC_VMEM | KMC_TOTAL),
1000
.maxlen = sizeof(unsigned long),
1001
.extra1 = &table_min,
1002
.extra2 = &table_max,
1004
.proc_handler = &proc_doslab,
1007
CTL_NAME (CTL_KMEM_SLAB_VMEMALLOC)
1008
.procname = "slab_vmem_alloc",
1009
.data = (void *)(KMC_VMEM | KMC_ALLOC),
1010
.maxlen = sizeof(unsigned long),
1011
.extra1 = &table_min,
1012
.extra2 = &table_max,
1014
.proc_handler = &proc_doslab,
1017
CTL_NAME (CTL_KMEM_SLAB_VMEMMAX)
1018
.procname = "slab_vmem_max",
1019
.data = (void *)(KMC_VMEM | KMC_MAX),
1020
.maxlen = sizeof(unsigned long),
1021
.extra1 = &table_min,
1022
.extra2 = &table_max,
1024
.proc_handler = &proc_doslab,
1028
#endif /* DEBUG_KMEM */
1030
static struct ctl_table spl_kstat_table[] = {
1034
static struct ctl_table spl_table[] = {
1035
/* NB No .strategy entries have been provided since
1036
* sysctl(8) prefers to go via /proc for portability.
1039
CTL_NAME (CTL_VERSION)
1040
.procname = "version",
1041
.data = spl_version,
1042
.maxlen = sizeof(spl_version),
1044
.proc_handler = &proc_dostring,
1047
CTL_NAME (CTL_HOSTID)
1048
.procname = "hostid",
1049
.data = &spl_hostid,
1050
.maxlen = sizeof(unsigned long),
1052
.proc_handler = &proc_dohostid,
1055
CTL_NAME (CTL_HW_SERIAL)
1056
.procname = "hw_serial",
1058
.maxlen = sizeof(hw_serial),
1060
.proc_handler = &proc_dostring,
1062
#ifndef HAVE_KALLSYMS_LOOKUP_NAME
1064
CTL_NAME (CTL_KALLSYMS)
1065
.procname = "kallsyms_lookup_name",
1066
.data = &spl_kallsyms_lookup_name_fn,
1067
.maxlen = sizeof(unsigned long),
1069
.proc_handler = &proc_dokallsyms_lookup_name,
1074
CTL_NAME (CTL_SPL_DEBUG)
1075
.procname = "debug",
1077
.child = spl_debug_table,
1081
CTL_NAME (CTL_SPL_VM)
1084
.child = spl_vm_table,
1088
CTL_NAME (CTL_SPL_KMEM)
1091
.child = spl_kmem_table,
1095
CTL_NAME (CTL_SPL_KSTAT)
1096
.procname = "kstat",
1098
.child = spl_kstat_table,
1103
static struct ctl_table spl_dir[] = {
1113
static struct ctl_table spl_root[] = {
1116
.procname = "kernel",
1124
proc_dir_entry_match(int len, const char *name, struct proc_dir_entry *de)
1126
if (de->namelen != len)
1129
return !memcmp(name, de->name, len);
1132
struct proc_dir_entry *
1133
proc_dir_entry_find(struct proc_dir_entry *root, const char *str)
1135
struct proc_dir_entry *de;
1137
for (de = root->subdir; de; de = de->next)
1138
if (proc_dir_entry_match(strlen(str), str, de))
1145
proc_dir_entries(struct proc_dir_entry *root)
1147
struct proc_dir_entry *de;
1150
for (de = root->subdir; de; de = de->next)
1162
#ifdef CONFIG_SYSCTL
1163
spl_header = spl_register_sysctl_table(spl_root, 0);
1164
if (spl_header == NULL)
1166
#endif /* CONFIG_SYSCTL */
1168
proc_spl = proc_mkdir("spl", NULL);
1169
if (proc_spl == NULL)
1170
SGOTO(out, rc = -EUNATCH);
1173
proc_spl_kmem = proc_mkdir("kmem", proc_spl);
1174
if (proc_spl_kmem == NULL)
1175
SGOTO(out, rc = -EUNATCH);
1177
proc_spl_kmem_slab = create_proc_entry("slab", 0444, proc_spl_kmem);
1178
if (proc_spl_kmem_slab == NULL)
1179
SGOTO(out, rc = -EUNATCH);
1181
proc_spl_kmem_slab->proc_fops = &proc_slab_operations;
1182
#endif /* DEBUG_KMEM */
1184
proc_spl_kstat = proc_mkdir("kstat", proc_spl);
1185
if (proc_spl_kstat == NULL)
1186
SGOTO(out, rc = -EUNATCH);
1189
remove_proc_entry("kstat", proc_spl);
1191
remove_proc_entry("slab", proc_spl_kmem);
1192
remove_proc_entry("kmem", proc_spl);
1194
remove_proc_entry("spl", NULL);
1195
#ifdef CONFIG_SYSCTL
1196
spl_unregister_sysctl_table(spl_header);
1197
#endif /* CONFIG_SYSCTL */
1208
remove_proc_entry("kstat", proc_spl);
1210
remove_proc_entry("slab", proc_spl_kmem);
1211
remove_proc_entry("kmem", proc_spl);
1213
remove_proc_entry("spl", NULL);
1215
#ifdef CONFIG_SYSCTL
1216
ASSERT(spl_header != NULL);
1217
spl_unregister_sysctl_table(spl_header);
1218
#endif /* CONFIG_SYSCTL */