2 * This file is part of the SPL: Solaris Porting Layer.
4 * Copyright (c) 2008 Lawrence Livermore National Security, LLC.
5 * Produced at Lawrence Livermore National Laboratory
7 * Brian Behlendorf <behlendorf1@llnl.gov>,
8 * Herb Wartens <wartens2@llnl.gov>,
9 * Jim Garlick <garlick@llnl.gov>
12 * This is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 #ifdef DEBUG_SUBSYSTEM
30 #undef DEBUG_SUBSYSTEM
33 #define DEBUG_SUBSYSTEM S_PROC
36 static unsigned long table_min
= 0;
37 static unsigned long table_max
= ~0;
41 static struct ctl_table_header
*spl_header
= NULL
;
42 #endif /* CONFIG_SYSCTL */
44 #if defined(DEBUG_MUTEX) || defined(DEBUG_KMEM) || defined(DEBUG_KSTAT)
45 static struct proc_dir_entry
*proc_spl
= NULL
;
47 static struct proc_dir_entry
*proc_spl_mutex
= NULL
;
48 static struct proc_dir_entry
*proc_spl_mutex_stats
= NULL
;
49 #endif /* DEBUG_MUTEX */
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 */
55 struct proc_dir_entry
*proc_spl_kstat
= NULL
;
56 #endif /* DEBUG_KSTAT */
57 #endif /* DEBUG_MUTEX || DEBUG_KMEM || DEBUG_KSTAT */
59 #ifdef HAVE_CTL_UNNUMBERED
61 #define CTL_SPL CTL_UNNUMBERED
62 #define CTL_SPL_DEBUG CTL_UNNUMBERED
63 #define CTL_SPL_VM CTL_UNNUMBERED
64 #define CTL_SPL_MUTEX CTL_UNNUMBERED
65 #define CTL_SPL_KMEM CTL_UNNUMBERED
66 #define CTL_SPL_KSTAT CTL_UNNUMBERED
68 #define CTL_VERSION CTL_UNNUMBERED /* Version */
69 #define CTL_HOSTID CTL_UNNUMBERED /* Host id by /usr/bin/hostid */
70 #define CTL_HW_SERIAL CTL_UNNUMBERED /* HW serial number by hostid */
71 #define CTL_KALLSYMS CTL_UNNUMBERED /* kallsyms_lookup_name addr */
73 #define CTL_DEBUG_SUBSYS CTL_UNNUMBERED /* Debug subsystem */
74 #define CTL_DEBUG_MASK CTL_UNNUMBERED /* Debug mask */
75 #define CTL_DEBUG_PRINTK CTL_UNNUMBERED /* All messages to console */
76 #define CTL_DEBUG_MB CTL_UNNUMBERED /* Debug buffer size */
77 #define CTL_DEBUG_BINARY CTL_UNNUMBERED /* Binary data in buffer */
78 #define CTL_DEBUG_CATASTROPHE CTL_UNNUMBERED /* Set if BUG'd or panic'd */
79 #define CTL_DEBUG_PANIC_ON_BUG CTL_UNNUMBERED /* Should panic on BUG */
80 #define CTL_DEBUG_PATH CTL_UNNUMBERED /* Dump log location */
81 #define CTL_DEBUG_DUMP CTL_UNNUMBERED /* Dump debug buffer to file */
82 #define CTL_DEBUG_FORCE_BUG CTL_UNNUMBERED /* Hook to force a BUG */
83 #define CTL_DEBUG_STACK_SIZE CTL_UNNUMBERED /* Max observed stack size */
85 #define CTL_CONSOLE_RATELIMIT CTL_UNNUMBERED /* Ratelimit console messages */
86 #define CTL_CONSOLE_MAX_DELAY_CS CTL_UNNUMBERED /* Max delay skip messages */
87 #define CTL_CONSOLE_MIN_DELAY_CS CTL_UNNUMBERED /* Init delay skip messages */
88 #define CTL_CONSOLE_BACKOFF CTL_UNNUMBERED /* Delay increase factor */
90 #define CTL_VM_MINFREE CTL_UNNUMBERED /* Minimum free memory */
91 #define CTL_VM_DESFREE CTL_UNNUMBERED /* Desired free memory */
92 #define CTL_VM_LOTSFREE CTL_UNNUMBERED /* Lots of free memory */
93 #define CTL_VM_NEEDFREE CTL_UNNUMBERED /* Need free memory */
94 #define CTL_VM_SWAPFS_MINFREE CTL_UNNUMBERED /* Minimum swapfs memory */
95 #define CTL_VM_SWAPFS_RESERVE CTL_UNNUMBERED /* Reserved swapfs memory */
96 #define CTL_VM_AVAILRMEM CTL_UNNUMBERED /* Easily available memory */
97 #define CTL_VM_FREEMEM CTL_UNNUMBERED /* Free memory */
98 #define CTL_VM_PHYSMEM CTL_UNNUMBERED /* Total physical memory */
101 #define CTL_KMEM_KMEMUSED CTL_UNNUMBERED /* Alloc'd kmem bytes */
102 #define CTL_KMEM_KMEMMAX CTL_UNNUMBERED /* Max alloc'd by kmem bytes */
103 #define CTL_KMEM_VMEMUSED CTL_UNNUMBERED /* Alloc'd vmem bytes */
104 #define CTL_KMEM_VMEMMAX CTL_UNNUMBERED /* Max alloc'd by vmem bytes */
105 #define CTL_KMEM_ALLOC_FAILED CTL_UNNUMBERED /* Cache allocations failed */
108 #define CTL_MUTEX_STATS CTL_UNNUMBERED /* Global mutex statistics */
109 #define CTL_MUTEX_STATS_PER CTL_UNNUMBERED /* Per mutex statistics */
110 #define CTL_MUTEX_SPIN_MAX CTL_UNNUMBERED /* Max mutex spin iterations */
112 #else /* HAVE_CTL_UNNUMBERED */
116 CTL_SPL_DEBUG
= 0x88,
118 CTL_SPL_MUTEX
= 0x90,
120 CTL_SPL_KSTAT
= 0x92,
124 CTL_VERSION
= 1, /* Version */
125 CTL_HOSTID
, /* Host id reported by /usr/bin/hostid */
126 CTL_HW_SERIAL
, /* Hardware serial number from hostid */
127 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 */
141 CTL_CONSOLE_RATELIMIT
, /* Ratelimit console messages */
142 CTL_CONSOLE_MAX_DELAY_CS
, /* Max delay which we skip messages */
143 CTL_CONSOLE_MIN_DELAY_CS
, /* Init delay which we skip messages */
144 CTL_CONSOLE_BACKOFF
, /* Delay increase factor */
146 CTL_VM_MINFREE
, /* Minimum free memory threshold */
147 CTL_VM_DESFREE
, /* Desired free memory threshold */
148 CTL_VM_LOTSFREE
, /* Lots of free memory threshold */
149 CTL_VM_NEEDFREE
, /* Need free memory deficit */
150 CTL_VM_SWAPFS_MINFREE
, /* Minimum swapfs memory */
151 CTL_VM_SWAPFS_RESERVE
, /* Reserved swapfs memory */
152 CTL_VM_AVAILRMEM
, /* Easily available memory */
153 CTL_VM_FREEMEM
, /* Free memory */
154 CTL_VM_PHYSMEM
, /* Total physical memory */
157 CTL_KMEM_KMEMUSED
, /* Alloc'd kmem bytes */
158 CTL_KMEM_KMEMMAX
, /* Max alloc'd by kmem bytes */
159 CTL_KMEM_VMEMUSED
, /* Alloc'd vmem bytes */
160 CTL_KMEM_VMEMMAX
, /* Max alloc'd by vmem bytes */
163 CTL_MUTEX_STATS
, /* Global mutex statistics */
164 CTL_MUTEX_STATS_PER
, /* Per mutex statistics */
165 CTL_MUTEX_SPIN_MAX
, /* Maximum mutex spin iterations */
167 #endif /* HAVE_CTL_UNNUMBERED */
170 proc_copyin_string(char *kbuffer
, int kbuffer_size
,
171 const char *ubuffer
, int ubuffer_size
)
175 if (ubuffer_size
> kbuffer_size
)
178 if (copy_from_user((void *)kbuffer
, (void *)ubuffer
, ubuffer_size
))
181 /* strip trailing whitespace */
182 size
= strnlen(kbuffer
, ubuffer_size
);
184 if (!isspace(kbuffer
[size
]))
191 /* no space to terminate */
192 if (size
== kbuffer_size
)
195 kbuffer
[size
+ 1] = 0;
200 proc_copyout_string(char *ubuffer
, int ubuffer_size
,
201 const char *kbuffer
, char *append
)
203 /* NB if 'append' != NULL, it's a single character to append to the
204 * copied out string - usually "\n", for /proc entries and
205 * (i.e. a terminating zero byte) for sysctl entries
207 int size
= MIN(strlen(kbuffer
), ubuffer_size
);
209 if (copy_to_user(ubuffer
, kbuffer
, size
))
212 if (append
!= NULL
&& size
< ubuffer_size
) {
213 if (copy_to_user(ubuffer
+ size
, append
, 1))
223 proc_dobitmasks(struct ctl_table
*table
, int write
, struct file
*filp
,
224 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
226 unsigned long *mask
= table
->data
;
227 int is_subsys
= (mask
== &spl_debug_subsys
) ? 1 : 0;
228 int is_printk
= (mask
== &spl_debug_printk
) ? 1 : 0;
233 str
= kmem_alloc(size
, KM_SLEEP
);
238 rc
= proc_copyin_string(str
, size
, buffer
, *lenp
);
242 rc
= spl_debug_str2mask(mask
, str
, is_subsys
);
243 /* Always print BUG/ASSERT to console, so keep this mask */
249 rc
= spl_debug_mask2str(str
, size
, *mask
, is_subsys
);
253 rc
= proc_copyout_string(buffer
, *lenp
,
261 kmem_free(str
, size
);
266 proc_debug_mb(struct ctl_table
*table
, int write
, struct file
*filp
,
267 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
274 rc
= proc_copyin_string(str
, sizeof(str
), buffer
, *lenp
);
278 rc
= spl_debug_set_mb(simple_strtoul(str
, NULL
, 0));
281 len
= snprintf(str
, sizeof(str
), "%d", spl_debug_get_mb());
285 rc
= proc_copyout_string(buffer
, *lenp
, str
+ *ppos
, "\n");
297 proc_dump_kernel(struct ctl_table
*table
, int write
, struct file
*filp
,
298 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
303 spl_debug_dumplog(0);
313 proc_force_bug(struct ctl_table
*table
, int write
, struct file
*filp
,
314 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
319 CERROR("Crashing due to forced SBUG\n");
330 proc_console_max_delay_cs(struct ctl_table
*table
, int write
, struct file
*filp
,
331 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
333 int rc
, max_delay_cs
;
334 struct ctl_table dummy
= *table
;
338 dummy
.data
= &max_delay_cs
;
339 dummy
.proc_handler
= &proc_dointvec
;
343 rc
= proc_dointvec(&dummy
, write
, filp
, buffer
, lenp
, ppos
);
347 if (max_delay_cs
<= 0)
350 d
= (max_delay_cs
* HZ
) / 100;
351 if (d
== 0 || d
< spl_console_min_delay
)
354 spl_console_max_delay
= d
;
356 max_delay_cs
= (spl_console_max_delay
* 100) / HZ
;
357 rc
= proc_dointvec(&dummy
, write
, filp
, buffer
, lenp
, ppos
);
364 proc_console_min_delay_cs(struct ctl_table
*table
, int write
, struct file
*filp
,
365 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
367 int rc
, min_delay_cs
;
368 struct ctl_table dummy
= *table
;
372 dummy
.data
= &min_delay_cs
;
373 dummy
.proc_handler
= &proc_dointvec
;
377 rc
= proc_dointvec(&dummy
, write
, filp
, buffer
, lenp
, ppos
);
381 if (min_delay_cs
<= 0)
384 d
= (min_delay_cs
* HZ
) / 100;
385 if (d
== 0 || d
> spl_console_max_delay
)
388 spl_console_min_delay
= d
;
390 min_delay_cs
= (spl_console_min_delay
* 100) / HZ
;
391 rc
= proc_dointvec(&dummy
, write
, filp
, buffer
, lenp
, ppos
);
398 proc_console_backoff(struct ctl_table
*table
, int write
, struct file
*filp
,
399 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
402 struct ctl_table dummy
= *table
;
405 dummy
.data
= &backoff
;
406 dummy
.proc_handler
= &proc_dointvec
;
410 rc
= proc_dointvec(&dummy
, write
, filp
, buffer
, lenp
, ppos
);
417 spl_console_backoff
= backoff
;
419 backoff
= spl_console_backoff
;
420 rc
= proc_dointvec(&dummy
, write
, filp
, buffer
, lenp
, ppos
);
428 proc_doatomic64(struct ctl_table
*table
, int write
, struct file
*filp
,
429 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
432 unsigned long min
= 0, max
= ~0, val
;
433 struct ctl_table dummy
= *table
;
437 dummy
.proc_handler
= &proc_dointvec
;
444 val
= atomic64_read((atomic64_t
*)table
->data
);
445 rc
= proc_doulongvec_minmax(&dummy
, write
, filp
,
451 #endif /* DEBUG_KMEM */
454 proc_dohostid(struct ctl_table
*table
, int write
, struct file
*filp
,
455 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
463 /* We can't use proc_doulongvec_minmax() in the write
464 * case hear because hostid while a hex value has no
465 * leading 0x which confuses the helper function. */
466 rc
= proc_copyin_string(str
, sizeof(str
), buffer
, *lenp
);
470 val
= simple_strtol(str
, &end
, 16);
474 spl_hostid
= (long) val
;
475 (void) snprintf(hw_serial
, HW_HOSTID_LEN
, "%u",
476 (val
>= 0) ? val
: -val
);
477 hw_serial
[HW_HOSTID_LEN
- 1] = '\0';
480 len
= snprintf(str
, sizeof(str
), "%lx", spl_hostid
);
484 rc
= proc_copyout_string(buffer
, *lenp
, str
+ *ppos
, "\n");
495 #ifndef HAVE_KALLSYMS_LOOKUP_NAME
497 proc_dokallsyms_lookup_name(struct ctl_table
*table
, int write
,
498 struct file
*filp
, void __user
*buffer
,
499 size_t *lenp
, loff_t
*ppos
) {
505 /* This may only be set once at module load time */
506 if (spl_kallsyms_lookup_name_fn
!= SYMBOL_POISON
)
509 /* We can't use proc_doulongvec_minmax() in the write
510 * case hear because the address while a hex value has no
511 * leading 0x which confuses the helper function. */
512 rc
= proc_copyin_string(str
, sizeof(str
), buffer
, *lenp
);
516 spl_kallsyms_lookup_name_fn
=
517 (kallsyms_lookup_name_t
)simple_strtoul(str
, &end
, 16);
523 len
= snprintf(str
, sizeof(str
), "%lx",
524 (unsigned long)spl_kallsyms_lookup_name_fn
);
528 rc
= proc_copyout_string(buffer
,*lenp
,str
+*ppos
,"\n");
538 #endif /* HAVE_KALLSYMS_LOOKUP_NAME */
541 proc_doavailrmem(struct ctl_table
*table
, int write
, struct file
*filp
,
542 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
551 len
= snprintf(str
, sizeof(str
), "%lu", (unsigned long)availrmem
);
555 rc
= proc_copyout_string(buffer
, *lenp
, str
+ *ppos
, "\n");
567 proc_dofreemem(struct ctl_table
*table
, int write
, struct file
*filp
,
568 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
577 len
= snprintf(str
, sizeof(str
), "%lu", (unsigned long)freemem
);
581 rc
= proc_copyout_string(buffer
, *lenp
, str
+ *ppos
, "\n");
594 mutex_seq_show_headers(struct seq_file
*f
)
596 seq_printf(f
, "%-36s %-4s %-16s\t"
597 "e_tot\te_nh\te_sp\te_sl\tte_tot\tte_nh\n",
598 "name", "type", "owner");
602 mutex_seq_show(struct seq_file
*f
, void *p
)
608 ASSERT(mp
->km_magic
== KM_MAGIC
);
610 switch (mp
->km_type
) {
611 case MUTEX_DEFAULT
: t
= 'D'; break;
612 case MUTEX_SPIN
: t
= 'S'; break;
613 case MUTEX_ADAPTIVE
: t
= 'A'; break;
617 seq_printf(f
, "%-36s %c ", mp
->km_name
, t
);
619 seq_printf(f
, "%p\t", mp
->km_owner
);
621 seq_printf(f
, "%-16s\t", "<not held>");
623 for (i
= 0; i
< MUTEX_STATS_SIZE
; i
++)
624 seq_printf(f
, "%d%c", mp
->km_stats
[i
],
625 (i
+ 1 == MUTEX_STATS_SIZE
) ? '\n' : '\t');
631 mutex_seq_start(struct seq_file
*f
, loff_t
*pos
)
637 spin_lock(&mutex_stats_lock
);
639 mutex_seq_show_headers(f
);
641 p
= mutex_stats_list
.next
;
644 if (p
== &mutex_stats_list
)
648 RETURN(list_entry(p
, kmutex_t
, km_list
));
652 mutex_seq_next(struct seq_file
*f
, void *p
, loff_t
*pos
)
658 RETURN((mp
->km_list
.next
== &mutex_stats_list
) ?
659 NULL
: list_entry(mp
->km_list
.next
, kmutex_t
, km_list
));
663 mutex_seq_stop(struct seq_file
*f
, void *v
)
665 spin_unlock(&mutex_stats_lock
);
668 static struct seq_operations mutex_seq_ops
= {
669 .show
= mutex_seq_show
,
670 .start
= mutex_seq_start
,
671 .next
= mutex_seq_next
,
672 .stop
= mutex_seq_stop
,
676 proc_mutex_open(struct inode
*inode
, struct file
*filp
)
678 return seq_open(filp
, &mutex_seq_ops
);
681 static struct file_operations proc_mutex_operations
= {
682 .open
= proc_mutex_open
,
685 .release
= seq_release
,
687 #endif /* DEBUG_MUTEX */
691 slab_seq_show_headers(struct seq_file
*f
)
693 seq_printf(f
, "%-36s\n", "name");
697 slab_seq_show(struct seq_file
*f
, void *p
)
699 spl_kmem_cache_t
*skc
= p
;
701 ASSERT(skc
->skc_magic
== SKC_MAGIC
);
703 spin_lock(&skc
->skc_lock
);
704 seq_printf(f
, "%-36s ", skc
->skc_name
);
705 seq_printf(f
, "%u %u %u - %lu %lu %lu - %lu %lu %lu - %lu %lu %lu\n",
706 (unsigned)skc
->skc_obj_size
,
707 (unsigned)skc
->skc_slab_objs
,
708 (unsigned)skc
->skc_slab_size
,
709 (long unsigned)skc
->skc_slab_fail
,
710 (long unsigned)skc
->skc_slab_create
,
711 (long unsigned)skc
->skc_slab_destroy
,
712 (long unsigned)skc
->skc_slab_total
,
713 (long unsigned)skc
->skc_slab_alloc
,
714 (long unsigned)skc
->skc_slab_max
,
715 (long unsigned)skc
->skc_obj_total
,
716 (long unsigned)skc
->skc_obj_alloc
,
717 (long unsigned)skc
->skc_obj_max
);
719 spin_unlock(&skc
->skc_lock
);
725 slab_seq_start(struct seq_file
*f
, loff_t
*pos
)
731 down_read(&spl_kmem_cache_sem
);
733 slab_seq_show_headers(f
);
735 p
= spl_kmem_cache_list
.next
;
738 if (p
== &spl_kmem_cache_list
)
742 RETURN(list_entry(p
, spl_kmem_cache_t
, skc_list
));
746 slab_seq_next(struct seq_file
*f
, void *p
, loff_t
*pos
)
748 spl_kmem_cache_t
*skc
= p
;
752 RETURN((skc
->skc_list
.next
== &spl_kmem_cache_list
) ?
753 NULL
: list_entry(skc
->skc_list
.next
, spl_kmem_cache_t
, skc_list
));
757 slab_seq_stop(struct seq_file
*f
, void *v
)
759 up_read(&spl_kmem_cache_sem
);
762 static struct seq_operations slab_seq_ops
= {
763 .show
= slab_seq_show
,
764 .start
= slab_seq_start
,
765 .next
= slab_seq_next
,
766 .stop
= slab_seq_stop
,
770 proc_slab_open(struct inode
*inode
, struct file
*filp
)
772 return seq_open(filp
, &slab_seq_ops
);
775 static struct file_operations proc_slab_operations
= {
776 .open
= proc_slab_open
,
779 .release
= seq_release
,
781 #endif /* DEBUG_KMEM */
783 static struct ctl_table spl_debug_table
[] = {
785 .ctl_name
= CTL_DEBUG_SUBSYS
,
786 .procname
= "subsystem",
787 .data
= &spl_debug_subsys
,
788 .maxlen
= sizeof(unsigned long),
790 .proc_handler
= &proc_dobitmasks
793 .ctl_name
= CTL_DEBUG_MASK
,
795 .data
= &spl_debug_mask
,
796 .maxlen
= sizeof(unsigned long),
798 .proc_handler
= &proc_dobitmasks
801 .ctl_name
= CTL_DEBUG_PRINTK
,
802 .procname
= "printk",
803 .data
= &spl_debug_printk
,
804 .maxlen
= sizeof(unsigned long),
806 .proc_handler
= &proc_dobitmasks
809 .ctl_name
= CTL_DEBUG_MB
,
812 .proc_handler
= &proc_debug_mb
,
815 .ctl_name
= CTL_DEBUG_BINARY
,
816 .procname
= "binary",
817 .data
= &spl_debug_binary
,
818 .maxlen
= sizeof(int),
820 .proc_handler
= &proc_dointvec
,
823 .ctl_name
= CTL_DEBUG_CATASTROPHE
,
824 .procname
= "catastrophe",
825 .data
= &spl_debug_catastrophe
,
826 .maxlen
= sizeof(int),
828 .proc_handler
= &proc_dointvec
,
831 .ctl_name
= CTL_DEBUG_PANIC_ON_BUG
,
832 .procname
= "panic_on_bug",
833 .data
= &spl_debug_panic_on_bug
,
834 .maxlen
= sizeof(int),
836 .proc_handler
= &proc_dointvec
839 .ctl_name
= CTL_DEBUG_PATH
,
841 .data
= spl_debug_file_path
,
842 .maxlen
= sizeof(spl_debug_file_path
),
844 .proc_handler
= &proc_dostring
,
847 .ctl_name
= CTL_DEBUG_DUMP
,
850 .proc_handler
= &proc_dump_kernel
,
852 { .ctl_name
= CTL_DEBUG_FORCE_BUG
,
853 .procname
= "force_bug",
855 .proc_handler
= &proc_force_bug
,
858 .ctl_name
= CTL_CONSOLE_RATELIMIT
,
859 .procname
= "console_ratelimit",
860 .data
= &spl_console_ratelimit
,
861 .maxlen
= sizeof(int),
863 .proc_handler
= &proc_dointvec
,
866 .ctl_name
= CTL_CONSOLE_MAX_DELAY_CS
,
867 .procname
= "console_max_delay_centisecs",
868 .maxlen
= sizeof(int),
870 .proc_handler
= &proc_console_max_delay_cs
,
873 .ctl_name
= CTL_CONSOLE_MIN_DELAY_CS
,
874 .procname
= "console_min_delay_centisecs",
875 .maxlen
= sizeof(int),
877 .proc_handler
= &proc_console_min_delay_cs
,
880 .ctl_name
= CTL_CONSOLE_BACKOFF
,
881 .procname
= "console_backoff",
882 .maxlen
= sizeof(int),
884 .proc_handler
= &proc_console_backoff
,
887 .ctl_name
= CTL_DEBUG_STACK_SIZE
,
888 .procname
= "stack_max",
889 .data
= &spl_debug_stack
,
890 .maxlen
= sizeof(int),
892 .proc_handler
= &proc_dointvec
,
897 static struct ctl_table spl_vm_table
[] = {
899 .ctl_name
= CTL_VM_MINFREE
,
900 .procname
= "minfree",
902 .maxlen
= sizeof(int),
904 .proc_handler
= &proc_dointvec
,
907 .ctl_name
= CTL_VM_DESFREE
,
908 .procname
= "desfree",
910 .maxlen
= sizeof(int),
912 .proc_handler
= &proc_dointvec
,
915 .ctl_name
= CTL_VM_LOTSFREE
,
916 .procname
= "lotsfree",
918 .maxlen
= sizeof(int),
920 .proc_handler
= &proc_dointvec
,
923 .ctl_name
= CTL_VM_NEEDFREE
,
924 .procname
= "needfree",
926 .maxlen
= sizeof(int),
928 .proc_handler
= &proc_dointvec
,
931 .ctl_name
= CTL_VM_SWAPFS_MINFREE
,
932 .procname
= "swapfs_minfree",
933 .data
= &swapfs_minfree
,
934 .maxlen
= sizeof(int),
936 .proc_handler
= &proc_dointvec
,
939 .ctl_name
= CTL_VM_SWAPFS_RESERVE
,
940 .procname
= "swapfs_reserve",
941 .data
= &swapfs_reserve
,
942 .maxlen
= sizeof(int),
944 .proc_handler
= &proc_dointvec
,
947 .ctl_name
= CTL_VM_AVAILRMEM
,
948 .procname
= "availrmem",
950 .proc_handler
= &proc_doavailrmem
,
953 .ctl_name
= CTL_VM_FREEMEM
,
954 .procname
= "freemem",
956 .maxlen
= sizeof(int),
958 .proc_handler
= &proc_dofreemem
,
961 .ctl_name
= CTL_VM_PHYSMEM
,
962 .procname
= "physmem",
964 .maxlen
= sizeof(int),
966 .proc_handler
= &proc_dointvec
,
972 static struct ctl_table spl_mutex_table
[] = {
974 .ctl_name
= CTL_MUTEX_STATS
,
976 .data
= &mutex_stats
,
977 .maxlen
= sizeof(int) * MUTEX_STATS_SIZE
,
979 .proc_handler
= &proc_dointvec
,
982 .ctl_name
= CTL_MUTEX_SPIN_MAX
,
983 .procname
= "spin_max",
984 .data
= &mutex_spin_max
,
985 .maxlen
= sizeof(int),
987 .proc_handler
= &proc_dointvec
,
991 #endif /* DEBUG_MUTEX */
994 static struct ctl_table spl_kmem_table
[] = {
996 .ctl_name
= CTL_KMEM_KMEMUSED
,
997 .procname
= "kmem_used",
998 .data
= &kmem_alloc_used
,
999 .maxlen
= sizeof(atomic64_t
),
1001 .proc_handler
= &proc_doatomic64
,
1004 .ctl_name
= CTL_KMEM_KMEMMAX
,
1005 .procname
= "kmem_max",
1006 .data
= &kmem_alloc_max
,
1007 .maxlen
= sizeof(unsigned long),
1008 .extra1
= &table_min
,
1009 .extra2
= &table_max
,
1011 .proc_handler
= &proc_doulongvec_minmax
,
1014 .ctl_name
= CTL_KMEM_VMEMUSED
,
1015 .procname
= "vmem_used",
1016 .data
= &vmem_alloc_used
,
1017 .maxlen
= sizeof(atomic64_t
),
1019 .proc_handler
= &proc_doatomic64
,
1022 .ctl_name
= CTL_KMEM_VMEMMAX
,
1023 .procname
= "vmem_max",
1024 .data
= &vmem_alloc_max
,
1025 .maxlen
= sizeof(unsigned long),
1026 .extra1
= &table_min
,
1027 .extra2
= &table_max
,
1029 .proc_handler
= &proc_doulongvec_minmax
,
1033 #endif /* DEBUG_KMEM */
1036 static struct ctl_table spl_kstat_table
[] = {
1039 #endif /* DEBUG_KSTAT */
1041 static struct ctl_table spl_table
[] = {
1042 /* NB No .strategy entries have been provided since
1043 * sysctl(8) prefers to go via /proc for portability.
1046 .ctl_name
= CTL_VERSION
,
1047 .procname
= "version",
1048 .data
= spl_version
,
1049 .maxlen
= sizeof(spl_version
),
1051 .proc_handler
= &proc_dostring
,
1054 .ctl_name
= CTL_HOSTID
,
1055 .procname
= "hostid",
1056 .data
= &spl_hostid
,
1057 .maxlen
= sizeof(unsigned long),
1059 .proc_handler
= &proc_dohostid
,
1062 .ctl_name
= CTL_HW_SERIAL
,
1063 .procname
= "hw_serial",
1065 .maxlen
= sizeof(hw_serial
),
1067 .proc_handler
= &proc_dostring
,
1069 #ifndef HAVE_KALLSYMS_LOOKUP_NAME
1071 .ctl_name
= CTL_KALLSYMS
,
1072 .procname
= "kallsyms_lookup_name",
1073 .data
= &spl_kallsyms_lookup_name_fn
,
1074 .maxlen
= sizeof(unsigned long),
1076 .proc_handler
= &proc_dokallsyms_lookup_name
,
1080 .ctl_name
= CTL_SPL_DEBUG
,
1081 .procname
= "debug",
1083 .child
= spl_debug_table
,
1086 .ctl_name
= CTL_SPL_VM
,
1089 .child
= spl_vm_table
,
1093 .ctl_name
= CTL_SPL_MUTEX
,
1094 .procname
= "mutex",
1096 .child
= spl_mutex_table
,
1101 .ctl_name
= CTL_SPL_KMEM
,
1104 .child
= spl_kmem_table
,
1109 .ctl_name
= CTL_SPL_KSTAT
,
1110 .procname
= "kstat",
1112 .child
= spl_kstat_table
,
1118 static struct ctl_table spl_dir
[] = {
1120 .ctl_name
= CTL_SPL
,
1128 static struct ctl_table spl_root
[] = {
1130 .ctl_name
= CTL_KERN
,
1131 .procname
= "kernel",
1139 proc_dir_entry_match(int len
, const char *name
, struct proc_dir_entry
*de
)
1141 if (de
->namelen
!= len
)
1144 return !memcmp(name
, de
->name
, len
);
1147 struct proc_dir_entry
*
1148 proc_dir_entry_find(struct proc_dir_entry
*root
, const char *str
)
1150 struct proc_dir_entry
*de
;
1152 for (de
= root
->subdir
; de
; de
= de
->next
)
1153 if (proc_dir_entry_match(strlen(str
), str
, de
))
1160 proc_dir_entries(struct proc_dir_entry
*root
)
1162 struct proc_dir_entry
*de
;
1165 for (de
= root
->subdir
; de
; de
= de
->next
)
1177 #ifdef CONFIG_SYSCTL
1178 spl_header
= spl_register_sysctl_table(spl_root
, 0);
1179 if (spl_header
== NULL
)
1181 #endif /* CONFIG_SYSCTL */
1183 #if defined(DEBUG_MUTEX) || defined(DEBUG_KMEM) || defined(DEBUG_KSTAT)
1184 proc_spl
= proc_mkdir("spl", NULL
);
1185 if (proc_spl
== NULL
)
1186 GOTO(out
, rc
= -EUNATCH
);
1189 proc_spl_mutex
= proc_mkdir("mutex", proc_spl
);
1190 if (proc_spl_mutex
== NULL
)
1191 GOTO(out
, rc
= -EUNATCH
);
1193 proc_spl_mutex_stats
= create_proc_entry("stats_per", 0444,
1195 if (proc_spl_mutex_stats
== NULL
)
1196 GOTO(out
, rc
= -EUNATCH
);
1198 proc_spl_mutex_stats
->proc_fops
= &proc_mutex_operations
;
1199 #endif /* DEBUG_MUTEX */
1202 proc_spl_kmem
= proc_mkdir("kmem", proc_spl
);
1203 if (proc_spl_kmem
== NULL
)
1204 GOTO(out
, rc
= -EUNATCH
);
1206 proc_spl_kmem_slab
= create_proc_entry("slab", 0444, proc_spl_kmem
);
1207 if (proc_spl_kmem_slab
== NULL
)
1208 GOTO(out
, rc
= -EUNATCH
);
1210 proc_spl_kmem_slab
->proc_fops
= &proc_slab_operations
;
1211 #endif /* DEBUG_KMEM */
1214 proc_spl_kstat
= proc_mkdir("kstat", proc_spl
);
1215 if (proc_spl_kstat
== NULL
)
1216 GOTO(out
, rc
= -EUNATCH
);
1217 #endif /* DEBUG_KSTAT */
1221 remove_proc_entry("kstat", proc_spl
);
1223 remove_proc_entry("slab", proc_spl_kmem
);
1225 remove_proc_entry("kmem", proc_spl
);
1227 remove_proc_entry("stats_per", proc_spl_mutex
);
1229 remove_proc_entry("mutex", proc_spl
);
1230 remove_proc_entry("spl", NULL
);
1231 #ifdef CONFIG_SYSCTL
1232 spl_unregister_sysctl_table(spl_header
);
1233 #endif /* CONFIG_SYSCTL */
1235 #endif /* DEBUG_MUTEX || DEBUG_KMEM || DEBUG_KSTAT */
1245 #if defined(DEBUG_MUTEX) || defined(DEBUG_KMEM) || defined(DEBUG_KSTAT)
1246 remove_proc_entry("kstat", proc_spl
);
1248 remove_proc_entry("slab", proc_spl_kmem
);
1250 remove_proc_entry("kmem", proc_spl
);
1252 remove_proc_entry("stats_per", proc_spl_mutex
);
1254 remove_proc_entry("mutex", proc_spl
);
1255 remove_proc_entry("spl", NULL
);
1256 #endif /* DEBUG_MUTEX || DEBUG_KMEM || DEBUG_KSTAT */
1258 #ifdef CONFIG_SYSCTL
1259 ASSERT(spl_header
!= NULL
);
1260 spl_unregister_sysctl_table(spl_header
);
1261 #endif /* CONFIG_SYSCTL */