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>
33 #ifdef DEBUG_SUBSYSTEM
34 #undef DEBUG_SUBSYSTEM
37 #define DEBUG_SUBSYSTEM S_PROC
40 static unsigned long table_min
= 0;
41 static unsigned long table_max
= ~0;
45 static struct ctl_table_header
*spl_header
= NULL
;
46 #endif /* CONFIG_SYSCTL */
48 static struct proc_dir_entry
*proc_spl
= NULL
;
50 static struct proc_dir_entry
*proc_spl_kmem
= NULL
;
51 static struct proc_dir_entry
*proc_spl_kmem_slab
= NULL
;
52 #endif /* DEBUG_KMEM */
53 struct proc_dir_entry
*proc_spl_kstat
= NULL
;
56 #ifdef HAVE_CTL_UNNUMBERED
58 #define CTL_SPL CTL_UNNUMBERED
59 #define CTL_SPL_DEBUG CTL_UNNUMBERED
60 #define CTL_SPL_VM CTL_UNNUMBERED
61 #define CTL_SPL_MUTEX CTL_UNNUMBERED
62 #define CTL_SPL_KMEM CTL_UNNUMBERED
63 #define CTL_SPL_KSTAT CTL_UNNUMBERED
65 #define CTL_VERSION CTL_UNNUMBERED /* Version */
66 #define CTL_HOSTID CTL_UNNUMBERED /* Host id by /usr/bin/hostid */
67 #define CTL_HW_SERIAL CTL_UNNUMBERED /* HW serial number by hostid */
68 #define CTL_KALLSYMS CTL_UNNUMBERED /* kallsyms_lookup_name addr */
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 */
87 #define CTL_VM_MINFREE CTL_UNNUMBERED /* Minimum free memory */
88 #define CTL_VM_DESFREE CTL_UNNUMBERED /* Desired free memory */
89 #define CTL_VM_LOTSFREE CTL_UNNUMBERED /* Lots of free memory */
90 #define CTL_VM_NEEDFREE CTL_UNNUMBERED /* Need free memory */
91 #define CTL_VM_SWAPFS_MINFREE CTL_UNNUMBERED /* Minimum swapfs memory */
92 #define CTL_VM_SWAPFS_RESERVE CTL_UNNUMBERED /* Reserved swapfs memory */
93 #define CTL_VM_AVAILRMEM CTL_UNNUMBERED /* Easily available memory */
94 #define CTL_VM_FREEMEM CTL_UNNUMBERED /* Free memory */
95 #define CTL_VM_PHYSMEM CTL_UNNUMBERED /* Total physical memory */
98 #define CTL_KMEM_KMEMUSED CTL_UNNUMBERED /* Alloc'd kmem bytes */
99 #define CTL_KMEM_KMEMMAX CTL_UNNUMBERED /* Max alloc'd by kmem bytes */
100 #define CTL_KMEM_VMEMUSED CTL_UNNUMBERED /* Alloc'd vmem bytes */
101 #define CTL_KMEM_VMEMMAX CTL_UNNUMBERED /* Max alloc'd by vmem bytes */
102 #define CTL_KMEM_ALLOC_FAILED CTL_UNNUMBERED /* Cache allocations failed */
105 #else /* HAVE_CTL_UNNUMBERED */
109 CTL_SPL_DEBUG
= 0x88,
111 CTL_SPL_MUTEX
= 0x90,
113 CTL_SPL_KSTAT
= 0x92,
117 CTL_VERSION
= 1, /* Version */
118 CTL_HOSTID
, /* Host id reported by /usr/bin/hostid */
119 CTL_HW_SERIAL
, /* Hardware serial number from hostid */
120 CTL_KALLSYMS
, /* Address of kallsyms_lookup_name */
122 CTL_DEBUG_SUBSYS
, /* Debug subsystem */
123 CTL_DEBUG_MASK
, /* Debug mask */
124 CTL_DEBUG_PRINTK
, /* Force all messages to console */
125 CTL_DEBUG_MB
, /* Debug buffer size */
126 CTL_DEBUG_BINARY
, /* Include binary data in buffer */
127 CTL_DEBUG_CATASTROPHE
, /* Set if we have BUG'd or panic'd */
128 CTL_DEBUG_PANIC_ON_BUG
, /* Set if we should panic on BUG */
129 CTL_DEBUG_PATH
, /* Dump log location */
130 CTL_DEBUG_DUMP
, /* Dump debug buffer to file */
131 CTL_DEBUG_FORCE_BUG
, /* Hook to force a BUG */
132 CTL_DEBUG_STACK_SIZE
, /* Max observed stack size */
134 CTL_CONSOLE_RATELIMIT
, /* Ratelimit console messages */
135 CTL_CONSOLE_MAX_DELAY_CS
, /* Max delay which we skip messages */
136 CTL_CONSOLE_MIN_DELAY_CS
, /* Init delay which we skip messages */
137 CTL_CONSOLE_BACKOFF
, /* Delay increase factor */
139 CTL_VM_MINFREE
, /* Minimum free memory threshold */
140 CTL_VM_DESFREE
, /* Desired free memory threshold */
141 CTL_VM_LOTSFREE
, /* Lots of free memory threshold */
142 CTL_VM_NEEDFREE
, /* Need free memory deficit */
143 CTL_VM_SWAPFS_MINFREE
, /* Minimum swapfs memory */
144 CTL_VM_SWAPFS_RESERVE
, /* Reserved swapfs memory */
145 CTL_VM_AVAILRMEM
, /* Easily available memory */
146 CTL_VM_FREEMEM
, /* Free memory */
147 CTL_VM_PHYSMEM
, /* Total physical memory */
150 CTL_KMEM_KMEMUSED
, /* Alloc'd kmem bytes */
151 CTL_KMEM_KMEMMAX
, /* Max alloc'd by kmem bytes */
152 CTL_KMEM_VMEMUSED
, /* Alloc'd vmem bytes */
153 CTL_KMEM_VMEMMAX
, /* Max alloc'd by vmem bytes */
156 #endif /* HAVE_CTL_UNNUMBERED */
157 #endif /* HAVE_CTL_NAME */
160 proc_copyin_string(char *kbuffer
, int kbuffer_size
,
161 const char *ubuffer
, int ubuffer_size
)
165 if (ubuffer_size
> kbuffer_size
)
168 if (copy_from_user((void *)kbuffer
, (void *)ubuffer
, ubuffer_size
))
171 /* strip trailing whitespace */
172 size
= strnlen(kbuffer
, ubuffer_size
);
174 if (!isspace(kbuffer
[size
]))
181 /* no space to terminate */
182 if (size
== kbuffer_size
)
185 kbuffer
[size
+ 1] = 0;
190 proc_copyout_string(char *ubuffer
, int ubuffer_size
,
191 const char *kbuffer
, char *append
)
193 /* NB if 'append' != NULL, it's a single character to append to the
194 * copied out string - usually "\n", for /proc entries and
195 * (i.e. a terminating zero byte) for sysctl entries
197 int size
= MIN(strlen(kbuffer
), ubuffer_size
);
199 if (copy_to_user(ubuffer
, kbuffer
, size
))
202 if (append
!= NULL
&& size
< ubuffer_size
) {
203 if (copy_to_user(ubuffer
+ size
, append
, 1))
212 SPL_PROC_HANDLER(proc_dobitmasks
)
214 unsigned long *mask
= table
->data
;
215 int is_subsys
= (mask
== &spl_debug_subsys
) ? 1 : 0;
216 int is_printk
= (mask
== &spl_debug_printk
) ? 1 : 0;
221 str
= kmem_alloc(size
, KM_SLEEP
);
226 rc
= proc_copyin_string(str
, size
, buffer
, *lenp
);
230 rc
= spl_debug_str2mask(mask
, str
, is_subsys
);
231 /* Always print BUG/ASSERT to console, so keep this mask */
237 rc
= spl_debug_mask2str(str
, size
, *mask
, is_subsys
);
241 rc
= proc_copyout_string(buffer
, *lenp
,
249 kmem_free(str
, size
);
253 SPL_PROC_HANDLER(proc_debug_mb
)
260 rc
= proc_copyin_string(str
, sizeof(str
), buffer
, *lenp
);
264 rc
= spl_debug_set_mb(simple_strtoul(str
, NULL
, 0));
267 len
= snprintf(str
, sizeof(str
), "%d", spl_debug_get_mb());
271 rc
= proc_copyout_string(buffer
,*lenp
,str
+*ppos
,"\n");
282 SPL_PROC_HANDLER(proc_dump_kernel
)
287 spl_debug_dumplog(0);
296 SPL_PROC_HANDLER(proc_force_bug
)
301 CERROR("Crashing due to forced SBUG\n");
311 SPL_PROC_HANDLER(proc_console_max_delay_cs
)
313 int rc
, max_delay_cs
;
314 struct ctl_table dummy
= *table
;
318 dummy
.data
= &max_delay_cs
;
319 dummy
.proc_handler
= &proc_dointvec
;
323 rc
= spl_proc_dointvec(&dummy
,write
,filp
,buffer
,lenp
,ppos
);
327 if (max_delay_cs
<= 0)
330 d
= (max_delay_cs
* HZ
) / 100;
331 if (d
== 0 || d
< spl_console_min_delay
)
334 spl_console_max_delay
= d
;
336 max_delay_cs
= (spl_console_max_delay
* 100) / HZ
;
337 rc
= spl_proc_dointvec(&dummy
,write
,filp
,buffer
,lenp
,ppos
);
343 SPL_PROC_HANDLER(proc_console_min_delay_cs
)
345 int rc
, min_delay_cs
;
346 struct ctl_table dummy
= *table
;
350 dummy
.data
= &min_delay_cs
;
351 dummy
.proc_handler
= &proc_dointvec
;
355 rc
= spl_proc_dointvec(&dummy
,write
,filp
,buffer
,lenp
,ppos
);
359 if (min_delay_cs
<= 0)
362 d
= (min_delay_cs
* HZ
) / 100;
363 if (d
== 0 || d
> spl_console_max_delay
)
366 spl_console_min_delay
= d
;
368 min_delay_cs
= (spl_console_min_delay
* 100) / HZ
;
369 rc
= spl_proc_dointvec(&dummy
,write
,filp
,buffer
,lenp
,ppos
);
375 SPL_PROC_HANDLER(proc_console_backoff
)
378 struct ctl_table dummy
= *table
;
381 dummy
.data
= &backoff
;
382 dummy
.proc_handler
= &proc_dointvec
;
386 rc
= spl_proc_dointvec(&dummy
,write
,filp
,buffer
,lenp
,ppos
);
393 spl_console_backoff
= backoff
;
395 backoff
= spl_console_backoff
;
396 rc
= spl_proc_dointvec(&dummy
,write
,filp
,buffer
,lenp
,ppos
);
403 SPL_PROC_HANDLER(proc_domemused
)
406 unsigned long min
= 0, max
= ~0, val
;
407 struct ctl_table dummy
= *table
;
411 dummy
.proc_handler
= &proc_dointvec
;
418 # ifdef HAVE_ATOMIC64_T
419 val
= atomic64_read((atomic64_t
*)table
->data
);
421 val
= atomic_read((atomic_t
*)table
->data
);
422 # endif /* HAVE_ATOMIC64_T */
423 rc
= spl_proc_doulongvec_minmax(&dummy
, write
, filp
,
429 #endif /* DEBUG_KMEM */
431 SPL_PROC_HANDLER(proc_dohostid
)
439 /* We can't use spl_proc_doulongvec_minmax() in the write
440 * case hear because hostid while a hex value has no
441 * leading 0x which confuses the helper function. */
442 rc
= proc_copyin_string(str
, sizeof(str
), buffer
, *lenp
);
446 val
= simple_strtol(str
, &end
, 16);
450 spl_hostid
= (long) val
;
451 (void) snprintf(hw_serial
, HW_HOSTID_LEN
, "%u",
452 (val
>= 0) ? val
: -val
);
453 hw_serial
[HW_HOSTID_LEN
- 1] = '\0';
456 len
= snprintf(str
, sizeof(str
), "%lx", spl_hostid
);
460 rc
= proc_copyout_string(buffer
,*lenp
,str
+*ppos
,"\n");
471 #ifndef HAVE_KALLSYMS_LOOKUP_NAME
472 SPL_PROC_HANDLER(proc_dokallsyms_lookup_name
)
479 /* This may only be set once at module load time */
480 if (spl_kallsyms_lookup_name_fn
!= SYMBOL_POISON
)
483 /* We can't use spl_proc_doulongvec_minmax() in the write
484 * case hear because the address while a hex value has no
485 * leading 0x which confuses the helper function. */
486 rc
= proc_copyin_string(str
, sizeof(str
), buffer
, *lenp
);
490 spl_kallsyms_lookup_name_fn
=
491 (kallsyms_lookup_name_t
)simple_strtoul(str
, &end
, 16);
497 len
= snprintf(str
, sizeof(str
), "%lx",
498 (unsigned long)spl_kallsyms_lookup_name_fn
);
502 rc
= proc_copyout_string(buffer
,*lenp
,str
+*ppos
,"\n");
512 #endif /* HAVE_KALLSYMS_LOOKUP_NAME */
514 SPL_PROC_HANDLER(proc_doavailrmem
)
523 len
= snprintf(str
, sizeof(str
), "%lu",
524 (unsigned long)availrmem
);
528 rc
= proc_copyout_string(buffer
,*lenp
,str
+*ppos
,"\n");
539 SPL_PROC_HANDLER(proc_dofreemem
)
548 len
= snprintf(str
, sizeof(str
), "%lu", (unsigned long)freemem
);
552 rc
= proc_copyout_string(buffer
,*lenp
,str
+*ppos
,"\n");
565 slab_seq_show_headers(struct seq_file
*f
)
567 seq_printf(f
, "%-36s %-6s - %s %s %s - %s %s %s - "
568 "%s %s %s - %s %s %s\n", "name", "flags",
569 "obj_size", "slab_objs", "slab_size",
570 "slab_fail", "slab_create", "slab_destroy",
571 "slab_total", "slab_alloc", "slab_max",
572 "obj_total", "obj_alloc", "obj_max");
576 slab_seq_show(struct seq_file
*f
, void *p
)
578 spl_kmem_cache_t
*skc
= p
;
580 ASSERT(skc
->skc_magic
== SKC_MAGIC
);
582 spin_lock(&skc
->skc_lock
);
583 seq_printf(f
, "%-36s ", skc
->skc_name
);
584 seq_printf(f
, "0x%04lx - %u %u %u - %lu %lu %lu - "
585 "%lu %lu %lu - %lu %lu %lu\n",
586 (long unsigned)skc
->skc_flags
,
587 (unsigned)skc
->skc_obj_size
,
588 (unsigned)skc
->skc_slab_objs
,
589 (unsigned)skc
->skc_slab_size
,
590 (long unsigned)skc
->skc_slab_fail
,
591 (long unsigned)skc
->skc_slab_create
,
592 (long unsigned)skc
->skc_slab_destroy
,
593 (long unsigned)skc
->skc_slab_total
,
594 (long unsigned)skc
->skc_slab_alloc
,
595 (long unsigned)skc
->skc_slab_max
,
596 (long unsigned)skc
->skc_obj_total
,
597 (long unsigned)skc
->skc_obj_alloc
,
598 (long unsigned)skc
->skc_obj_max
);
600 spin_unlock(&skc
->skc_lock
);
606 slab_seq_start(struct seq_file
*f
, loff_t
*pos
)
612 down_read(&spl_kmem_cache_sem
);
614 slab_seq_show_headers(f
);
616 p
= spl_kmem_cache_list
.next
;
619 if (p
== &spl_kmem_cache_list
)
623 RETURN(list_entry(p
, spl_kmem_cache_t
, skc_list
));
627 slab_seq_next(struct seq_file
*f
, void *p
, loff_t
*pos
)
629 spl_kmem_cache_t
*skc
= p
;
633 RETURN((skc
->skc_list
.next
== &spl_kmem_cache_list
) ?
634 NULL
: list_entry(skc
->skc_list
.next
,spl_kmem_cache_t
,skc_list
));
638 slab_seq_stop(struct seq_file
*f
, void *v
)
640 up_read(&spl_kmem_cache_sem
);
643 static struct seq_operations slab_seq_ops
= {
644 .show
= slab_seq_show
,
645 .start
= slab_seq_start
,
646 .next
= slab_seq_next
,
647 .stop
= slab_seq_stop
,
651 proc_slab_open(struct inode
*inode
, struct file
*filp
)
653 return seq_open(filp
, &slab_seq_ops
);
656 static struct file_operations proc_slab_operations
= {
657 .open
= proc_slab_open
,
660 .release
= seq_release
,
662 #endif /* DEBUG_KMEM */
664 static struct ctl_table spl_debug_table
[] = {
666 CTL_NAME (CTL_DEBUG_SUBSYS
)
667 .procname
= "subsystem",
668 .data
= &spl_debug_subsys
,
669 .maxlen
= sizeof(unsigned long),
671 .proc_handler
= &proc_dobitmasks
674 CTL_NAME (CTL_DEBUG_MASK
)
676 .data
= &spl_debug_mask
,
677 .maxlen
= sizeof(unsigned long),
679 .proc_handler
= &proc_dobitmasks
682 CTL_NAME (CTL_DEBUG_PRINTK
)
683 .procname
= "printk",
684 .data
= &spl_debug_printk
,
685 .maxlen
= sizeof(unsigned long),
687 .proc_handler
= &proc_dobitmasks
690 CTL_NAME (CTL_DEBUG_MB
)
693 .proc_handler
= &proc_debug_mb
,
696 CTL_NAME (CTL_DEBUG_BINARY
)
697 .procname
= "binary",
698 .data
= &spl_debug_binary
,
699 .maxlen
= sizeof(int),
701 .proc_handler
= &proc_dointvec
,
704 CTL_NAME (CTL_DEBUG_CATASTROPHE
)
705 .procname
= "catastrophe",
706 .data
= &spl_debug_catastrophe
,
707 .maxlen
= sizeof(int),
709 .proc_handler
= &proc_dointvec
,
712 CTL_NAME (CTL_DEBUG_PANIC_ON_BUG
)
713 .procname
= "panic_on_bug",
714 .data
= &spl_debug_panic_on_bug
,
715 .maxlen
= sizeof(int),
717 .proc_handler
= &proc_dointvec
720 CTL_NAME (CTL_DEBUG_PATH
)
722 .data
= spl_debug_file_path
,
723 .maxlen
= sizeof(spl_debug_file_path
),
725 .proc_handler
= &proc_dostring
,
728 CTL_NAME (CTL_DEBUG_DUMP
)
731 .proc_handler
= &proc_dump_kernel
,
733 { CTL_NAME (CTL_DEBUG_FORCE_BUG
)
734 .procname
= "force_bug",
736 .proc_handler
= &proc_force_bug
,
739 CTL_NAME (CTL_CONSOLE_RATELIMIT
)
740 .procname
= "console_ratelimit",
741 .data
= &spl_console_ratelimit
,
742 .maxlen
= sizeof(int),
744 .proc_handler
= &proc_dointvec
,
747 CTL_NAME (CTL_CONSOLE_MAX_DELAY_CS
)
748 .procname
= "console_max_delay_centisecs",
749 .maxlen
= sizeof(int),
751 .proc_handler
= &proc_console_max_delay_cs
,
754 CTL_NAME (CTL_CONSOLE_MIN_DELAY_CS
)
755 .procname
= "console_min_delay_centisecs",
756 .maxlen
= sizeof(int),
758 .proc_handler
= &proc_console_min_delay_cs
,
761 CTL_NAME (CTL_CONSOLE_BACKOFF
)
762 .procname
= "console_backoff",
763 .maxlen
= sizeof(int),
765 .proc_handler
= &proc_console_backoff
,
768 CTL_NAME (CTL_DEBUG_STACK_SIZE
)
769 .procname
= "stack_max",
770 .data
= &spl_debug_stack
,
771 .maxlen
= sizeof(int),
773 .proc_handler
= &proc_dointvec
,
778 static struct ctl_table spl_vm_table
[] = {
780 CTL_NAME (CTL_VM_MINFREE
)
781 .procname
= "minfree",
783 .maxlen
= sizeof(int),
785 .proc_handler
= &proc_dointvec
,
788 CTL_NAME (CTL_VM_DESFREE
)
789 .procname
= "desfree",
791 .maxlen
= sizeof(int),
793 .proc_handler
= &proc_dointvec
,
796 CTL_NAME (CTL_VM_LOTSFREE
)
797 .procname
= "lotsfree",
799 .maxlen
= sizeof(int),
801 .proc_handler
= &proc_dointvec
,
804 CTL_NAME (CTL_VM_NEEDFREE
)
805 .procname
= "needfree",
807 .maxlen
= sizeof(int),
809 .proc_handler
= &proc_dointvec
,
812 CTL_NAME (CTL_VM_SWAPFS_MINFREE
)
813 .procname
= "swapfs_minfree",
814 .data
= &swapfs_minfree
,
815 .maxlen
= sizeof(int),
817 .proc_handler
= &proc_dointvec
,
820 CTL_NAME (CTL_VM_SWAPFS_RESERVE
)
821 .procname
= "swapfs_reserve",
822 .data
= &swapfs_reserve
,
823 .maxlen
= sizeof(int),
825 .proc_handler
= &proc_dointvec
,
828 CTL_NAME (CTL_VM_AVAILRMEM
)
829 .procname
= "availrmem",
831 .proc_handler
= &proc_doavailrmem
,
834 CTL_NAME (CTL_VM_FREEMEM
)
835 .procname
= "freemem",
837 .maxlen
= sizeof(int),
839 .proc_handler
= &proc_dofreemem
,
842 CTL_NAME (CTL_VM_PHYSMEM
)
843 .procname
= "physmem",
845 .maxlen
= sizeof(int),
847 .proc_handler
= &proc_dointvec
,
853 static struct ctl_table spl_kmem_table
[] = {
855 CTL_NAME (CTL_KMEM_KMEMUSED
)
856 .procname
= "kmem_used",
857 .data
= &kmem_alloc_used
,
858 # ifdef HAVE_ATOMIC64_T
859 .maxlen
= sizeof(atomic64_t
),
861 .maxlen
= sizeof(atomic_t
),
862 # endif /* HAVE_ATOMIC64_T */
864 .proc_handler
= &proc_domemused
,
867 CTL_NAME (CTL_KMEM_KMEMMAX
)
868 .procname
= "kmem_max",
869 .data
= &kmem_alloc_max
,
870 .maxlen
= sizeof(unsigned long),
871 .extra1
= &table_min
,
872 .extra2
= &table_max
,
874 .proc_handler
= &proc_doulongvec_minmax
,
877 CTL_NAME (CTL_KMEM_VMEMUSED
)
878 .procname
= "vmem_used",
879 .data
= &vmem_alloc_used
,
880 # ifdef HAVE_ATOMIC64_T
881 .maxlen
= sizeof(atomic64_t
),
883 .maxlen
= sizeof(atomic_t
),
884 # endif /* HAVE_ATOMIC64_T */
886 .proc_handler
= &proc_domemused
,
889 CTL_NAME (CTL_KMEM_VMEMMAX
)
890 .procname
= "vmem_max",
891 .data
= &vmem_alloc_max
,
892 .maxlen
= sizeof(unsigned long),
893 .extra1
= &table_min
,
894 .extra2
= &table_max
,
896 .proc_handler
= &proc_doulongvec_minmax
,
900 #endif /* DEBUG_KMEM */
902 static struct ctl_table spl_kstat_table
[] = {
906 static struct ctl_table spl_table
[] = {
907 /* NB No .strategy entries have been provided since
908 * sysctl(8) prefers to go via /proc for portability.
911 CTL_NAME (CTL_VERSION
)
912 .procname
= "version",
914 .maxlen
= sizeof(spl_version
),
916 .proc_handler
= &proc_dostring
,
919 CTL_NAME (CTL_HOSTID
)
920 .procname
= "hostid",
922 .maxlen
= sizeof(unsigned long),
924 .proc_handler
= &proc_dohostid
,
927 CTL_NAME (CTL_HW_SERIAL
)
928 .procname
= "hw_serial",
930 .maxlen
= sizeof(hw_serial
),
932 .proc_handler
= &proc_dostring
,
934 #ifndef HAVE_KALLSYMS_LOOKUP_NAME
936 CTL_NAME (CTL_KALLSYMS
)
937 .procname
= "kallsyms_lookup_name",
938 .data
= &spl_kallsyms_lookup_name_fn
,
939 .maxlen
= sizeof(unsigned long),
941 .proc_handler
= &proc_dokallsyms_lookup_name
,
945 CTL_NAME (CTL_SPL_DEBUG
)
948 .child
= spl_debug_table
,
951 CTL_NAME (CTL_SPL_VM
)
954 .child
= spl_vm_table
,
958 CTL_NAME (CTL_SPL_KMEM
)
961 .child
= spl_kmem_table
,
965 CTL_NAME (CTL_SPL_KSTAT
)
968 .child
= spl_kstat_table
,
973 static struct ctl_table spl_dir
[] = {
983 static struct ctl_table spl_root
[] = {
986 .procname
= "kernel",
994 proc_dir_entry_match(int len
, const char *name
, struct proc_dir_entry
*de
)
996 if (de
->namelen
!= len
)
999 return !memcmp(name
, de
->name
, len
);
1002 struct proc_dir_entry
*
1003 proc_dir_entry_find(struct proc_dir_entry
*root
, const char *str
)
1005 struct proc_dir_entry
*de
;
1007 for (de
= root
->subdir
; de
; de
= de
->next
)
1008 if (proc_dir_entry_match(strlen(str
), str
, de
))
1015 proc_dir_entries(struct proc_dir_entry
*root
)
1017 struct proc_dir_entry
*de
;
1020 for (de
= root
->subdir
; de
; de
= de
->next
)
1032 #ifdef CONFIG_SYSCTL
1033 spl_header
= spl_register_sysctl_table(spl_root
, 0);
1034 if (spl_header
== NULL
)
1036 #endif /* CONFIG_SYSCTL */
1038 proc_spl
= proc_mkdir("spl", NULL
);
1039 if (proc_spl
== NULL
)
1040 GOTO(out
, rc
= -EUNATCH
);
1043 proc_spl_kmem
= proc_mkdir("kmem", proc_spl
);
1044 if (proc_spl_kmem
== NULL
)
1045 GOTO(out
, rc
= -EUNATCH
);
1047 proc_spl_kmem_slab
= create_proc_entry("slab", 0444, proc_spl_kmem
);
1048 if (proc_spl_kmem_slab
== NULL
)
1049 GOTO(out
, rc
= -EUNATCH
);
1051 proc_spl_kmem_slab
->proc_fops
= &proc_slab_operations
;
1052 #endif /* DEBUG_KMEM */
1054 proc_spl_kstat
= proc_mkdir("kstat", proc_spl
);
1055 if (proc_spl_kstat
== NULL
)
1056 GOTO(out
, rc
= -EUNATCH
);
1059 remove_proc_entry("kstat", proc_spl
);
1061 remove_proc_entry("slab", proc_spl_kmem
);
1062 remove_proc_entry("kmem", proc_spl
);
1064 remove_proc_entry("spl", NULL
);
1065 #ifdef CONFIG_SYSCTL
1066 spl_unregister_sysctl_table(spl_header
);
1067 #endif /* CONFIG_SYSCTL */
1078 remove_proc_entry("kstat", proc_spl
);
1080 remove_proc_entry("slab", proc_spl_kmem
);
1081 remove_proc_entry("kmem", proc_spl
);
1083 remove_proc_entry("spl", NULL
);
1085 #ifdef CONFIG_SYSCTL
1086 ASSERT(spl_header
!= NULL
);
1087 spl_unregister_sysctl_table(spl_header
);
1088 #endif /* CONFIG_SYSCTL */