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 #endif /* DEBUG_KMEM */
54 struct proc_dir_entry
*proc_spl_kstat
= NULL
;
55 #endif /* DEBUG_KSTAT */
56 #endif /* DEBUG_MUTEX || DEBUG_KMEM || DEBUG_KSTAT */
58 #ifdef HAVE_CTL_UNNUMBERED
60 #define CTL_SPL CTL_UNNUMBERED
61 #define CTL_SPL_DEBUG 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 */
70 #define CTL_DEBUG_SUBSYS CTL_UNNUMBERED /* Debug subsystem */
71 #define CTL_DEBUG_MASK CTL_UNNUMBERED /* Debug mask */
72 #define CTL_DEBUG_PRINTK CTL_UNNUMBERED /* All messages to console */
73 #define CTL_DEBUG_MB CTL_UNNUMBERED /* Debug buffer size */
74 #define CTL_DEBUG_BINARY CTL_UNNUMBERED /* Binary data in buffer */
75 #define CTL_DEBUG_CATASTROPHE CTL_UNNUMBERED /* Set if BUG'd or panic'd */
76 #define CTL_DEBUG_PANIC_ON_BUG CTL_UNNUMBERED /* Should panic on BUG */
77 #define CTL_DEBUG_PATH CTL_UNNUMBERED /* Dump log location */
78 #define CTL_DEBUG_DUMP CTL_UNNUMBERED /* Dump debug buffer to file */
79 #define CTL_DEBUG_FORCE_BUG CTL_UNNUMBERED /* Hook to force a BUG */
80 #define CTL_DEBUG_STACK_SIZE CTL_UNNUMBERED /* Max observed stack size */
82 #define CTL_CONSOLE_RATELIMIT CTL_UNNUMBERED /* Ratelimit console messages */
83 #define CTL_CONSOLE_MAX_DELAY_CS CTL_UNNUMBERED /* Max delay skip messages */
84 #define CTL_CONSOLE_MIN_DELAY_CS CTL_UNNUMBERED /* Init delay skip messages */
85 #define CTL_CONSOLE_BACKOFF CTL_UNNUMBERED /* Delay increase factor */
88 #define CTL_KMEM_KMEMUSED CTL_UNNUMBERED /* Alloc'd kmem bytes */
89 #define CTL_KMEM_KMEMMAX CTL_UNNUMBERED /* Max alloc'd by kmem bytes */
90 #define CTL_KMEM_VMEMUSED CTL_UNNUMBERED /* Alloc'd vmem bytes */
91 #define CTL_KMEM_VMEMMAX CTL_UNNUMBERED /* Max alloc'd by vmem bytes */
92 #define CTL_KMEM_ALLOC_FAILED CTL_UNNUMBERED /* Cache allocations failed */
95 #define CTL_MUTEX_STATS CTL_UNNUMBERED /* Global mutex statistics */
96 #define CTL_MUTEX_STATS_PER CTL_UNNUMBERED /* Per mutex statistics */
97 #define CTL_MUTEX_SPIN_MAX CTL_UNNUMBERED /* Max mutex spin iterations */
99 #else /* HAVE_CTL_UNNUMBERED */
102 #define CTL_SPL_DEBUG 0x88
103 #define CTL_SPL_MUTEX 0x89
104 #define CTL_SPL_KMEM 0x90
105 #define CTL_SPL_KSTAT 0x91
108 CTL_VERSION
= 1, /* Version */
109 CTL_HOSTID
, /* Host id reported by /usr/bin/hostid */
110 CTL_HW_SERIAL
, /* Hardware serial number from hostid */
112 CTL_DEBUG_SUBSYS
, /* Debug subsystem */
113 CTL_DEBUG_MASK
, /* Debug mask */
114 CTL_DEBUG_PRINTK
, /* Force all messages to console */
115 CTL_DEBUG_MB
, /* Debug buffer size */
116 CTL_DEBUG_BINARY
, /* Include binary data in buffer */
117 CTL_DEBUG_CATASTROPHE
, /* Set if we have BUG'd or panic'd */
118 CTL_DEBUG_PANIC_ON_BUG
, /* Set if we should panic on BUG */
119 CTL_DEBUG_PATH
, /* Dump log location */
120 CTL_DEBUG_DUMP
, /* Dump debug buffer to file */
121 CTL_DEBUG_FORCE_BUG
, /* Hook to force a BUG */
122 CTL_DEBUG_STACK_SIZE
, /* Max observed stack size */
124 CTL_CONSOLE_RATELIMIT
, /* Ratelimit console messages */
125 CTL_CONSOLE_MAX_DELAY_CS
, /* Max delay at which we skip messages */
126 CTL_CONSOLE_MIN_DELAY_CS
, /* Init delay at which we skip messages */
127 CTL_CONSOLE_BACKOFF
, /* Delay increase factor */
130 CTL_KMEM_KMEMUSED
, /* Alloc'd kmem bytes */
131 CTL_KMEM_KMEMMAX
, /* Max alloc'd by kmem bytes */
132 CTL_KMEM_VMEMUSED
, /* Alloc'd vmem bytes */
133 CTL_KMEM_VMEMMAX
, /* Max alloc'd by vmem bytes */
134 CTL_KMEM_ALLOC_FAILED
, /* Cache allocation failed */
137 CTL_MUTEX_STATS
, /* Global mutex statistics */
138 CTL_MUTEX_STATS_PER
, /* Per mutex statistics */
139 CTL_MUTEX_SPIN_MAX
, /* Maximum mutex spin iterations */
141 #endif /* HAVE_CTL_UNNUMBERED */
144 proc_copyin_string(char *kbuffer
, int kbuffer_size
,
145 const char *ubuffer
, int ubuffer_size
)
149 if (ubuffer_size
> kbuffer_size
)
152 if (copy_from_user((void *)kbuffer
, (void *)ubuffer
, ubuffer_size
))
155 /* strip trailing whitespace */
156 size
= strnlen(kbuffer
, ubuffer_size
);
158 if (!isspace(kbuffer
[size
]))
165 /* no space to terminate */
166 if (size
== kbuffer_size
)
169 kbuffer
[size
+ 1] = 0;
174 proc_copyout_string(char *ubuffer
, int ubuffer_size
,
175 const char *kbuffer
, char *append
)
177 /* NB if 'append' != NULL, it's a single character to append to the
178 * copied out string - usually "\n", for /proc entries and
179 * (i.e. a terminating zero byte) for sysctl entries
181 int size
= MIN(strlen(kbuffer
), ubuffer_size
);
183 if (copy_to_user(ubuffer
, kbuffer
, size
))
186 if (append
!= NULL
&& size
< ubuffer_size
) {
187 if (copy_to_user(ubuffer
+ size
, append
, 1))
197 proc_dobitmasks(struct ctl_table
*table
, int write
, struct file
*filp
,
198 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
200 unsigned long *mask
= table
->data
;
201 int is_subsys
= (mask
== &spl_debug_subsys
) ? 1 : 0;
202 int is_printk
= (mask
== &spl_debug_printk
) ? 1 : 0;
207 str
= kmem_alloc(size
, KM_SLEEP
);
212 rc
= proc_copyin_string(str
, size
, buffer
, *lenp
);
216 rc
= spl_debug_str2mask(mask
, str
, is_subsys
);
217 /* Always print BUG/ASSERT to console, so keep this mask */
223 rc
= spl_debug_mask2str(str
, size
, *mask
, is_subsys
);
227 rc
= proc_copyout_string(buffer
, *lenp
,
235 kmem_free(str
, size
);
240 proc_debug_mb(struct ctl_table
*table
, int write
, struct file
*filp
,
241 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
248 rc
= proc_copyin_string(str
, sizeof(str
), buffer
, *lenp
);
252 rc
= spl_debug_set_mb(simple_strtoul(str
, NULL
, 0));
255 len
= snprintf(str
, sizeof(str
), "%d", spl_debug_get_mb());
259 rc
= proc_copyout_string(buffer
, *lenp
, str
+ *ppos
, "\n");
271 proc_dump_kernel(struct ctl_table
*table
, int write
, struct file
*filp
,
272 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
277 spl_debug_dumplog(0);
287 proc_force_bug(struct ctl_table
*table
, int write
, struct file
*filp
,
288 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
293 CERROR("Crashing due to forced SBUG\n");
304 proc_console_max_delay_cs(struct ctl_table
*table
, int write
, struct file
*filp
,
305 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
307 int rc
, max_delay_cs
;
308 struct ctl_table dummy
= *table
;
312 dummy
.data
= &max_delay_cs
;
313 dummy
.proc_handler
= &proc_dointvec
;
317 rc
= proc_dointvec(&dummy
, write
, filp
, buffer
, lenp
, ppos
);
321 if (max_delay_cs
<= 0)
324 d
= (max_delay_cs
* HZ
) / 100;
325 if (d
== 0 || d
< spl_console_min_delay
)
328 spl_console_max_delay
= d
;
330 max_delay_cs
= (spl_console_max_delay
* 100) / HZ
;
331 rc
= proc_dointvec(&dummy
, write
, filp
, buffer
, lenp
, ppos
);
338 proc_console_min_delay_cs(struct ctl_table
*table
, int write
, struct file
*filp
,
339 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
341 int rc
, min_delay_cs
;
342 struct ctl_table dummy
= *table
;
346 dummy
.data
= &min_delay_cs
;
347 dummy
.proc_handler
= &proc_dointvec
;
351 rc
= proc_dointvec(&dummy
, write
, filp
, buffer
, lenp
, ppos
);
355 if (min_delay_cs
<= 0)
358 d
= (min_delay_cs
* HZ
) / 100;
359 if (d
== 0 || d
> spl_console_max_delay
)
362 spl_console_min_delay
= d
;
364 min_delay_cs
= (spl_console_min_delay
* 100) / HZ
;
365 rc
= proc_dointvec(&dummy
, write
, filp
, buffer
, lenp
, ppos
);
372 proc_console_backoff(struct ctl_table
*table
, int write
, struct file
*filp
,
373 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
376 struct ctl_table dummy
= *table
;
379 dummy
.data
= &backoff
;
380 dummy
.proc_handler
= &proc_dointvec
;
384 rc
= proc_dointvec(&dummy
, write
, filp
, buffer
, lenp
, ppos
);
391 spl_console_backoff
= backoff
;
393 backoff
= spl_console_backoff
;
394 rc
= proc_dointvec(&dummy
, write
, filp
, buffer
, lenp
, ppos
);
402 proc_doatomic64(struct ctl_table
*table
, int write
, struct file
*filp
,
403 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
406 unsigned long min
= 0, max
= ~0, val
;
407 struct ctl_table dummy
= *table
;
411 dummy
.proc_handler
= &proc_dointvec
;
418 val
= atomic_read((atomic64_t
*)table
->data
);
419 rc
= proc_doulongvec_minmax(&dummy
, write
, filp
,
425 #endif /* DEBUG_KMEM */
428 proc_dohostid(struct ctl_table
*table
, int write
, struct file
*filp
,
429 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
437 /* We can't use proc_doulongvec_minmax() in the write
438 * case hear because hostid while a hex value has no
439 * leading 0x which confuses the helper function. */
440 rc
= proc_copyin_string(str
, sizeof(str
), buffer
, *lenp
);
444 val
= simple_strtol(str
, &end
, 16);
448 spl_hostid
= (long)val
;
449 sprintf(hw_serial
, "%u", (val
>= 0) ? val
: -val
);
452 len
= snprintf(str
, sizeof(str
), "%lx", spl_hostid
);
456 rc
= proc_copyout_string(buffer
, *lenp
, str
+ *ppos
, "\n");
469 mutex_seq_show_headers(struct seq_file
*f
)
471 seq_printf(f
, "%-36s %-4s %-16s\t"
472 "e_tot\te_nh\te_sp\te_sl\tte_tot\tte_nh\n",
473 "name", "type", "owner");
477 mutex_seq_show(struct seq_file
*f
, void *p
)
483 ASSERT(mp
->km_magic
== KM_MAGIC
);
485 switch (mp
->km_type
) {
486 case MUTEX_DEFAULT
: t
= 'D'; break;
487 case MUTEX_SPIN
: t
= 'S'; break;
488 case MUTEX_ADAPTIVE
: t
= 'A'; break;
492 seq_printf(f
, "%-36s %c ", mp
->km_name
, t
);
494 seq_printf(f
, "%p\t", mp
->km_owner
);
496 seq_printf(f
, "%-16s\t", "<not held>");
498 for (i
= 0; i
< MUTEX_STATS_SIZE
; i
++)
499 seq_printf(f
, "%d%c", mp
->km_stats
[i
],
500 (i
+ 1 == MUTEX_STATS_SIZE
) ? '\n' : '\t');
506 mutex_seq_start(struct seq_file
*f
, loff_t
*pos
)
512 spin_lock(&mutex_stats_lock
);
514 mutex_seq_show_headers(f
);
516 p
= mutex_stats_list
.next
;
519 if (p
== &mutex_stats_list
)
523 RETURN(list_entry(p
, kmutex_t
, km_list
));
527 mutex_seq_next(struct seq_file
*f
, void *p
, loff_t
*pos
)
533 RETURN((mp
->km_list
.next
== &mutex_stats_list
) ?
534 NULL
: list_entry(mp
->km_list
.next
, kmutex_t
, km_list
));
538 mutex_seq_stop(struct seq_file
*f
, void *v
)
540 spin_unlock(&mutex_stats_lock
);
543 static struct seq_operations mutex_seq_ops
= {
544 .show
= mutex_seq_show
,
545 .start
= mutex_seq_start
,
546 .next
= mutex_seq_next
,
547 .stop
= mutex_seq_stop
,
551 proc_mutex_open(struct inode
*inode
, struct file
*filp
)
553 return seq_open(filp
, &mutex_seq_ops
);
556 static struct file_operations proc_mutex_operations
= {
557 .open
= proc_mutex_open
,
560 .release
= seq_release
,
562 #endif /* DEBUG_MUTEX */
564 static struct ctl_table spl_debug_table
[] = {
566 .ctl_name
= CTL_DEBUG_SUBSYS
,
567 .procname
= "subsystem",
568 .data
= &spl_debug_subsys
,
569 .maxlen
= sizeof(unsigned long),
571 .proc_handler
= &proc_dobitmasks
574 .ctl_name
= CTL_DEBUG_MASK
,
576 .data
= &spl_debug_mask
,
577 .maxlen
= sizeof(unsigned long),
579 .proc_handler
= &proc_dobitmasks
582 .ctl_name
= CTL_DEBUG_PRINTK
,
583 .procname
= "printk",
584 .data
= &spl_debug_printk
,
585 .maxlen
= sizeof(unsigned long),
587 .proc_handler
= &proc_dobitmasks
590 .ctl_name
= CTL_DEBUG_MB
,
593 .proc_handler
= &proc_debug_mb
,
596 .ctl_name
= CTL_DEBUG_BINARY
,
597 .procname
= "binary",
598 .data
= &spl_debug_binary
,
599 .maxlen
= sizeof(int),
601 .proc_handler
= &proc_dointvec
,
604 .ctl_name
= CTL_DEBUG_CATASTROPHE
,
605 .procname
= "catastrophe",
606 .data
= &spl_debug_catastrophe
,
607 .maxlen
= sizeof(int),
609 .proc_handler
= &proc_dointvec
,
612 .ctl_name
= CTL_DEBUG_PANIC_ON_BUG
,
613 .procname
= "panic_on_bug",
614 .data
= &spl_debug_panic_on_bug
,
615 .maxlen
= sizeof(int),
617 .proc_handler
= &proc_dointvec
620 .ctl_name
= CTL_DEBUG_PATH
,
622 .data
= spl_debug_file_path
,
623 .maxlen
= sizeof(spl_debug_file_path
),
625 .proc_handler
= &proc_dostring
,
628 .ctl_name
= CTL_DEBUG_DUMP
,
631 .proc_handler
= &proc_dump_kernel
,
633 { .ctl_name
= CTL_DEBUG_FORCE_BUG
,
634 .procname
= "force_bug",
636 .proc_handler
= &proc_force_bug
,
639 .ctl_name
= CTL_CONSOLE_RATELIMIT
,
640 .procname
= "console_ratelimit",
641 .data
= &spl_console_ratelimit
,
642 .maxlen
= sizeof(int),
644 .proc_handler
= &proc_dointvec
,
647 .ctl_name
= CTL_CONSOLE_MAX_DELAY_CS
,
648 .procname
= "console_max_delay_centisecs",
649 .maxlen
= sizeof(int),
651 .proc_handler
= &proc_console_max_delay_cs
,
654 .ctl_name
= CTL_CONSOLE_MIN_DELAY_CS
,
655 .procname
= "console_min_delay_centisecs",
656 .maxlen
= sizeof(int),
658 .proc_handler
= &proc_console_min_delay_cs
,
661 .ctl_name
= CTL_CONSOLE_BACKOFF
,
662 .procname
= "console_backoff",
663 .maxlen
= sizeof(int),
665 .proc_handler
= &proc_console_backoff
,
668 .ctl_name
= CTL_DEBUG_STACK_SIZE
,
669 .procname
= "stack_max",
670 .data
= &spl_debug_stack
,
671 .maxlen
= sizeof(int),
673 .proc_handler
= &proc_dointvec
,
679 static struct ctl_table spl_mutex_table
[] = {
681 .ctl_name
= CTL_MUTEX_STATS
,
683 .data
= &mutex_stats
,
684 .maxlen
= sizeof(int) * MUTEX_STATS_SIZE
,
686 .proc_handler
= &proc_dointvec
,
689 .ctl_name
= CTL_MUTEX_SPIN_MAX
,
690 .procname
= "spin_max",
691 .data
= &mutex_spin_max
,
692 .maxlen
= sizeof(int),
694 .proc_handler
= &proc_dointvec
,
698 #endif /* DEBUG_MUTEX */
701 static struct ctl_table spl_kmem_table
[] = {
703 .ctl_name
= CTL_KMEM_KMEMUSED
,
704 .procname
= "kmem_used",
705 .data
= &kmem_alloc_used
,
706 .maxlen
= sizeof(atomic64_t
),
708 .proc_handler
= &proc_doatomic64
,
711 .ctl_name
= CTL_KMEM_KMEMMAX
,
712 .procname
= "kmem_max",
713 .data
= &kmem_alloc_max
,
714 .maxlen
= sizeof(unsigned long),
715 .extra1
= &table_min
,
716 .extra2
= &table_max
,
718 .proc_handler
= &proc_doulongvec_minmax
,
721 .ctl_name
= CTL_KMEM_VMEMUSED
,
722 .procname
= "vmem_used",
723 .data
= &vmem_alloc_used
,
724 .maxlen
= sizeof(atomic64_t
),
726 .proc_handler
= &proc_doatomic64
,
729 .ctl_name
= CTL_KMEM_VMEMMAX
,
730 .procname
= "vmem_max",
731 .data
= &vmem_alloc_max
,
732 .maxlen
= sizeof(unsigned long),
733 .extra1
= &table_min
,
734 .extra2
= &table_max
,
736 .proc_handler
= &proc_doulongvec_minmax
,
739 .ctl_name
= CTL_KMEM_ALLOC_FAILED
,
740 .procname
= "kmem_alloc_failed",
741 .data
= &kmem_cache_alloc_failed
,
742 .maxlen
= sizeof(atomic64_t
),
744 .proc_handler
= &proc_doatomic64
,
748 #endif /* DEBUG_KMEM */
751 static struct ctl_table spl_kstat_table
[] = {
754 #endif /* DEBUG_KSTAT */
756 static struct ctl_table spl_table
[] = {
757 /* NB No .strategy entries have been provided since
758 * sysctl(8) prefers to go via /proc for portability.
761 .ctl_name
= CTL_VERSION
,
762 .procname
= "version",
764 .maxlen
= sizeof(spl_version
),
766 .proc_handler
= &proc_dostring
,
769 .ctl_name
= CTL_HOSTID
,
770 .procname
= "hostid",
772 .maxlen
= sizeof(unsigned long),
774 .proc_handler
= &proc_dohostid
,
777 .ctl_name
= CTL_HW_SERIAL
,
778 .procname
= "hw_serial",
780 .maxlen
= sizeof(hw_serial
),
782 .proc_handler
= &proc_dostring
,
785 .ctl_name
= CTL_SPL_DEBUG
,
788 .child
= spl_debug_table
,
792 .ctl_name
= CTL_SPL_MUTEX
,
795 .child
= spl_mutex_table
,
800 .ctl_name
= CTL_SPL_KMEM
,
803 .child
= spl_kmem_table
,
808 .ctl_name
= CTL_SPL_KSTAT
,
811 .child
= spl_kstat_table
,
817 static struct ctl_table spl_dir
[] = {
827 static struct ctl_table spl_root
[] = {
829 .ctl_name
= CTL_KERN
,
830 .procname
= "kernel",
838 proc_dir_entry_match(int len
, const char *name
, struct proc_dir_entry
*de
)
840 if (de
->namelen
!= len
)
843 return !memcmp(name
, de
->name
, len
);
846 struct proc_dir_entry
*
847 proc_dir_entry_find(struct proc_dir_entry
*root
, const char *str
)
849 struct proc_dir_entry
*de
;
851 for (de
= root
->subdir
; de
; de
= de
->next
)
852 if (proc_dir_entry_match(strlen(str
), str
, de
))
859 proc_dir_entries(struct proc_dir_entry
*root
)
861 struct proc_dir_entry
*de
;
864 for (de
= root
->subdir
; de
; de
= de
->next
)
877 spl_header
= spl_register_sysctl_table(spl_root
, 0);
878 if (spl_header
== NULL
)
880 #endif /* CONFIG_SYSCTL */
882 #if defined(DEBUG_MUTEX) || defined(DEBUG_KMEM) || defined(DEBUG_KSTAT)
883 proc_spl
= proc_mkdir("spl", NULL
);
884 if (proc_spl
== NULL
)
885 GOTO(out
, rc
= -EUNATCH
);
888 proc_spl_mutex
= proc_mkdir("mutex", proc_spl
);
889 if (proc_spl_mutex
== NULL
)
890 GOTO(out
, rc
= -EUNATCH
);
892 proc_spl_mutex_stats
= create_proc_entry("stats_per", 0444,
894 if (proc_spl_mutex_stats
== NULL
)
895 GOTO(out
, rc
= -EUNATCH
);
897 proc_spl_mutex_stats
->proc_fops
= &proc_mutex_operations
;
898 #endif /* DEBUG_MUTEX */
901 proc_spl_kmem
= proc_mkdir("kmem", proc_spl
);
902 if (proc_spl_kmem
== NULL
)
903 GOTO(out
, rc
= -EUNATCH
);
904 #endif /* DEBUG_KMEM */
907 proc_spl_kstat
= proc_mkdir("kstat", proc_spl
);
908 if (proc_spl_kstat
== NULL
)
909 GOTO(out
, rc
= -EUNATCH
);
910 #endif /* DEBUG_KSTAT */
914 remove_proc_entry("kstat", proc_spl
);
915 remove_proc_entry("kmem", proc_spl
);
916 remove_proc_entry("stats_per", proc_spl_mutex
);
917 remove_proc_entry("mutex", proc_spl
);
919 spl_unregister_sysctl_table(spl_header
);
920 #endif /* CONFIG_SYSCTL */
922 #endif /* DEBUG_MUTEX || DEBUG_KMEM || DEBUG_KSTAT */
932 #if defined(DEBUG_MUTEX) || defined(DEBUG_KMEM) || defined(DEBUG_KSTAT)
933 remove_proc_entry("kstat", proc_spl
);
934 remove_proc_entry("kmem", proc_spl
);
935 remove_proc_entry("stats_per", proc_spl_mutex
);
936 remove_proc_entry("mutex", proc_spl
);
937 #endif /* DEBUG_MUTEX || DEBUG_KMEM || DEBUG_KSTAT */
940 ASSERT(spl_header
!= NULL
);
941 spl_unregister_sysctl_table(spl_header
);
942 #endif /* CONFIG_SYSCTL */