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://github.com/behlendorf/spl/>.
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 */