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
;
55 #ifdef HAVE_CTL_UNNUMBERED
57 #define CTL_SPL CTL_UNNUMBERED
58 #define CTL_SPL_DEBUG CTL_UNNUMBERED
59 #define CTL_SPL_VM CTL_UNNUMBERED
60 #define CTL_SPL_MUTEX CTL_UNNUMBERED
61 #define CTL_SPL_KMEM CTL_UNNUMBERED
62 #define CTL_SPL_KSTAT CTL_UNNUMBERED
64 #define CTL_VERSION CTL_UNNUMBERED /* Version */
65 #define CTL_HOSTID CTL_UNNUMBERED /* Host id by /usr/bin/hostid */
66 #define CTL_HW_SERIAL CTL_UNNUMBERED /* HW serial number by hostid */
67 #define CTL_KALLSYMS CTL_UNNUMBERED /* kallsyms_lookup_name addr */
69 #define CTL_DEBUG_SUBSYS CTL_UNNUMBERED /* Debug subsystem */
70 #define CTL_DEBUG_MASK CTL_UNNUMBERED /* Debug mask */
71 #define CTL_DEBUG_PRINTK CTL_UNNUMBERED /* All messages to console */
72 #define CTL_DEBUG_MB CTL_UNNUMBERED /* Debug buffer size */
73 #define CTL_DEBUG_BINARY CTL_UNNUMBERED /* Binary data in buffer */
74 #define CTL_DEBUG_CATASTROPHE CTL_UNNUMBERED /* Set if BUG'd or panic'd */
75 #define CTL_DEBUG_PANIC_ON_BUG CTL_UNNUMBERED /* Should panic on BUG */
76 #define CTL_DEBUG_PATH CTL_UNNUMBERED /* Dump log location */
77 #define CTL_DEBUG_DUMP CTL_UNNUMBERED /* Dump debug buffer to file */
78 #define CTL_DEBUG_FORCE_BUG CTL_UNNUMBERED /* Hook to force a BUG */
79 #define CTL_DEBUG_STACK_SIZE CTL_UNNUMBERED /* Max observed stack size */
81 #define CTL_CONSOLE_RATELIMIT CTL_UNNUMBERED /* Ratelimit console messages */
82 #define CTL_CONSOLE_MAX_DELAY_CS CTL_UNNUMBERED /* Max delay skip messages */
83 #define CTL_CONSOLE_MIN_DELAY_CS CTL_UNNUMBERED /* Init delay skip messages */
84 #define CTL_CONSOLE_BACKOFF CTL_UNNUMBERED /* Delay increase factor */
86 #define CTL_VM_MINFREE CTL_UNNUMBERED /* Minimum free memory */
87 #define CTL_VM_DESFREE CTL_UNNUMBERED /* Desired free memory */
88 #define CTL_VM_LOTSFREE CTL_UNNUMBERED /* Lots of free memory */
89 #define CTL_VM_NEEDFREE CTL_UNNUMBERED /* Need free memory */
90 #define CTL_VM_SWAPFS_MINFREE CTL_UNNUMBERED /* Minimum swapfs memory */
91 #define CTL_VM_SWAPFS_RESERVE CTL_UNNUMBERED /* Reserved swapfs memory */
92 #define CTL_VM_AVAILRMEM CTL_UNNUMBERED /* Easily available memory */
93 #define CTL_VM_FREEMEM CTL_UNNUMBERED /* Free memory */
94 #define CTL_VM_PHYSMEM CTL_UNNUMBERED /* Total physical memory */
97 #define CTL_KMEM_KMEMUSED CTL_UNNUMBERED /* Alloc'd kmem bytes */
98 #define CTL_KMEM_KMEMMAX CTL_UNNUMBERED /* Max alloc'd by kmem bytes */
99 #define CTL_KMEM_VMEMUSED CTL_UNNUMBERED /* Alloc'd vmem bytes */
100 #define CTL_KMEM_VMEMMAX CTL_UNNUMBERED /* Max alloc'd by vmem bytes */
101 #define CTL_KMEM_ALLOC_FAILED CTL_UNNUMBERED /* Cache allocations failed */
104 #else /* HAVE_CTL_UNNUMBERED */
108 CTL_SPL_DEBUG
= 0x88,
110 CTL_SPL_MUTEX
= 0x90,
112 CTL_SPL_KSTAT
= 0x92,
116 CTL_VERSION
= 1, /* Version */
117 CTL_HOSTID
, /* Host id reported by /usr/bin/hostid */
118 CTL_HW_SERIAL
, /* Hardware serial number from hostid */
119 CTL_KALLSYMS
, /* Address of kallsyms_lookup_name */
121 CTL_DEBUG_SUBSYS
, /* Debug subsystem */
122 CTL_DEBUG_MASK
, /* Debug mask */
123 CTL_DEBUG_PRINTK
, /* Force all messages to console */
124 CTL_DEBUG_MB
, /* Debug buffer size */
125 CTL_DEBUG_BINARY
, /* Include binary data in buffer */
126 CTL_DEBUG_CATASTROPHE
, /* Set if we have BUG'd or panic'd */
127 CTL_DEBUG_PANIC_ON_BUG
, /* Set if we should panic on BUG */
128 CTL_DEBUG_PATH
, /* Dump log location */
129 CTL_DEBUG_DUMP
, /* Dump debug buffer to file */
130 CTL_DEBUG_FORCE_BUG
, /* Hook to force a BUG */
131 CTL_DEBUG_STACK_SIZE
, /* Max observed stack size */
133 CTL_CONSOLE_RATELIMIT
, /* Ratelimit console messages */
134 CTL_CONSOLE_MAX_DELAY_CS
, /* Max delay which we skip messages */
135 CTL_CONSOLE_MIN_DELAY_CS
, /* Init delay which we skip messages */
136 CTL_CONSOLE_BACKOFF
, /* Delay increase factor */
138 CTL_VM_MINFREE
, /* Minimum free memory threshold */
139 CTL_VM_DESFREE
, /* Desired free memory threshold */
140 CTL_VM_LOTSFREE
, /* Lots of free memory threshold */
141 CTL_VM_NEEDFREE
, /* Need free memory deficit */
142 CTL_VM_SWAPFS_MINFREE
, /* Minimum swapfs memory */
143 CTL_VM_SWAPFS_RESERVE
, /* Reserved swapfs memory */
144 CTL_VM_AVAILRMEM
, /* Easily available memory */
145 CTL_VM_FREEMEM
, /* Free memory */
146 CTL_VM_PHYSMEM
, /* Total physical memory */
149 CTL_KMEM_KMEMUSED
, /* Alloc'd kmem bytes */
150 CTL_KMEM_KMEMMAX
, /* Max alloc'd by kmem bytes */
151 CTL_KMEM_VMEMUSED
, /* Alloc'd vmem bytes */
152 CTL_KMEM_VMEMMAX
, /* Max alloc'd by vmem bytes */
155 #endif /* HAVE_CTL_UNNUMBERED */
158 proc_copyin_string(char *kbuffer
, int kbuffer_size
,
159 const char *ubuffer
, int ubuffer_size
)
163 if (ubuffer_size
> kbuffer_size
)
166 if (copy_from_user((void *)kbuffer
, (void *)ubuffer
, ubuffer_size
))
169 /* strip trailing whitespace */
170 size
= strnlen(kbuffer
, ubuffer_size
);
172 if (!isspace(kbuffer
[size
]))
179 /* no space to terminate */
180 if (size
== kbuffer_size
)
183 kbuffer
[size
+ 1] = 0;
188 proc_copyout_string(char *ubuffer
, int ubuffer_size
,
189 const char *kbuffer
, char *append
)
191 /* NB if 'append' != NULL, it's a single character to append to the
192 * copied out string - usually "\n", for /proc entries and
193 * (i.e. a terminating zero byte) for sysctl entries
195 int size
= MIN(strlen(kbuffer
), ubuffer_size
);
197 if (copy_to_user(ubuffer
, kbuffer
, size
))
200 if (append
!= NULL
&& size
< ubuffer_size
) {
201 if (copy_to_user(ubuffer
+ size
, append
, 1))
210 SPL_PROC_HANDLER(proc_dobitmasks
)
212 unsigned long *mask
= table
->data
;
213 int is_subsys
= (mask
== &spl_debug_subsys
) ? 1 : 0;
214 int is_printk
= (mask
== &spl_debug_printk
) ? 1 : 0;
219 str
= kmem_alloc(size
, KM_SLEEP
);
224 rc
= proc_copyin_string(str
, size
, buffer
, *lenp
);
228 rc
= spl_debug_str2mask(mask
, str
, is_subsys
);
229 /* Always print BUG/ASSERT to console, so keep this mask */
235 rc
= spl_debug_mask2str(str
, size
, *mask
, is_subsys
);
239 rc
= proc_copyout_string(buffer
, *lenp
,
247 kmem_free(str
, size
);
251 SPL_PROC_HANDLER(proc_debug_mb
)
258 rc
= proc_copyin_string(str
, sizeof(str
), buffer
, *lenp
);
262 rc
= spl_debug_set_mb(simple_strtoul(str
, NULL
, 0));
265 len
= snprintf(str
, sizeof(str
), "%d", spl_debug_get_mb());
269 rc
= proc_copyout_string(buffer
,*lenp
,str
+*ppos
,"\n");
280 SPL_PROC_HANDLER(proc_dump_kernel
)
285 spl_debug_dumplog(0);
294 SPL_PROC_HANDLER(proc_force_bug
)
299 CERROR("Crashing due to forced SBUG\n");
309 SPL_PROC_HANDLER(proc_console_max_delay_cs
)
311 int rc
, max_delay_cs
;
312 struct ctl_table dummy
= *table
;
316 dummy
.data
= &max_delay_cs
;
317 dummy
.proc_handler
= &proc_dointvec
;
321 rc
= spl_proc_dointvec(&dummy
,write
,filp
,buffer
,lenp
,ppos
);
325 if (max_delay_cs
<= 0)
328 d
= (max_delay_cs
* HZ
) / 100;
329 if (d
== 0 || d
< spl_console_min_delay
)
332 spl_console_max_delay
= d
;
334 max_delay_cs
= (spl_console_max_delay
* 100) / HZ
;
335 rc
= spl_proc_dointvec(&dummy
,write
,filp
,buffer
,lenp
,ppos
);
341 SPL_PROC_HANDLER(proc_console_min_delay_cs
)
343 int rc
, min_delay_cs
;
344 struct ctl_table dummy
= *table
;
348 dummy
.data
= &min_delay_cs
;
349 dummy
.proc_handler
= &proc_dointvec
;
353 rc
= spl_proc_dointvec(&dummy
,write
,filp
,buffer
,lenp
,ppos
);
357 if (min_delay_cs
<= 0)
360 d
= (min_delay_cs
* HZ
) / 100;
361 if (d
== 0 || d
> spl_console_max_delay
)
364 spl_console_min_delay
= d
;
366 min_delay_cs
= (spl_console_min_delay
* 100) / HZ
;
367 rc
= spl_proc_dointvec(&dummy
,write
,filp
,buffer
,lenp
,ppos
);
373 SPL_PROC_HANDLER(proc_console_backoff
)
376 struct ctl_table dummy
= *table
;
379 dummy
.data
= &backoff
;
380 dummy
.proc_handler
= &proc_dointvec
;
384 rc
= spl_proc_dointvec(&dummy
,write
,filp
,buffer
,lenp
,ppos
);
391 spl_console_backoff
= backoff
;
393 backoff
= spl_console_backoff
;
394 rc
= spl_proc_dointvec(&dummy
,write
,filp
,buffer
,lenp
,ppos
);
401 SPL_PROC_HANDLER(proc_domemused
)
404 unsigned long min
= 0, max
= ~0, val
;
405 struct ctl_table dummy
= *table
;
409 dummy
.proc_handler
= &proc_dointvec
;
416 # ifdef HAVE_ATOMIC64_T
417 val
= atomic64_read((atomic64_t
*)table
->data
);
419 val
= atomic_read((atomic_t
*)table
->data
);
420 # endif /* HAVE_ATOMIC64_T */
421 rc
= spl_proc_doulongvec_minmax(&dummy
, write
, filp
,
427 #endif /* DEBUG_KMEM */
429 SPL_PROC_HANDLER(proc_dohostid
)
437 /* We can't use spl_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 (void) snprintf(hw_serial
, HW_HOSTID_LEN
, "%u",
450 (val
>= 0) ? val
: -val
);
451 hw_serial
[HW_HOSTID_LEN
- 1] = '\0';
454 len
= snprintf(str
, sizeof(str
), "%lx", spl_hostid
);
458 rc
= proc_copyout_string(buffer
,*lenp
,str
+*ppos
,"\n");
469 #ifndef HAVE_KALLSYMS_LOOKUP_NAME
470 SPL_PROC_HANDLER(proc_dokallsyms_lookup_name
)
477 /* This may only be set once at module load time */
478 if (spl_kallsyms_lookup_name_fn
!= SYMBOL_POISON
)
481 /* We can't use spl_proc_doulongvec_minmax() in the write
482 * case hear because the address while a hex value has no
483 * leading 0x which confuses the helper function. */
484 rc
= proc_copyin_string(str
, sizeof(str
), buffer
, *lenp
);
488 spl_kallsyms_lookup_name_fn
=
489 (kallsyms_lookup_name_t
)simple_strtoul(str
, &end
, 16);
495 len
= snprintf(str
, sizeof(str
), "%lx",
496 (unsigned long)spl_kallsyms_lookup_name_fn
);
500 rc
= proc_copyout_string(buffer
,*lenp
,str
+*ppos
,"\n");
510 #endif /* HAVE_KALLSYMS_LOOKUP_NAME */
512 SPL_PROC_HANDLER(proc_doavailrmem
)
521 len
= snprintf(str
, sizeof(str
), "%lu",
522 (unsigned long)availrmem
);
526 rc
= proc_copyout_string(buffer
,*lenp
,str
+*ppos
,"\n");
537 SPL_PROC_HANDLER(proc_dofreemem
)
546 len
= snprintf(str
, sizeof(str
), "%lu", (unsigned long)freemem
);
550 rc
= proc_copyout_string(buffer
,*lenp
,str
+*ppos
,"\n");
563 slab_seq_show_headers(struct seq_file
*f
)
565 seq_printf(f
, "%-36s %-6s - %s %s %s - %s %s %s - "
566 "%s %s %s - %s %s %s\n", "name", "flags",
567 "obj_size", "slab_objs", "slab_size",
568 "slab_fail", "slab_create", "slab_destroy",
569 "slab_total", "slab_alloc", "slab_max",
570 "obj_total", "obj_alloc", "obj_max");
574 slab_seq_show(struct seq_file
*f
, void *p
)
576 spl_kmem_cache_t
*skc
= p
;
578 ASSERT(skc
->skc_magic
== SKC_MAGIC
);
580 spin_lock(&skc
->skc_lock
);
581 seq_printf(f
, "%-36s ", skc
->skc_name
);
582 seq_printf(f
, "0x%04lx - %u %u %u - %lu %lu %lu - "
583 "%lu %lu %lu - %lu %lu %lu\n",
584 (long unsigned)skc
->skc_flags
,
585 (unsigned)skc
->skc_obj_size
,
586 (unsigned)skc
->skc_slab_objs
,
587 (unsigned)skc
->skc_slab_size
,
588 (long unsigned)skc
->skc_slab_fail
,
589 (long unsigned)skc
->skc_slab_create
,
590 (long unsigned)skc
->skc_slab_destroy
,
591 (long unsigned)skc
->skc_slab_total
,
592 (long unsigned)skc
->skc_slab_alloc
,
593 (long unsigned)skc
->skc_slab_max
,
594 (long unsigned)skc
->skc_obj_total
,
595 (long unsigned)skc
->skc_obj_alloc
,
596 (long unsigned)skc
->skc_obj_max
);
598 spin_unlock(&skc
->skc_lock
);
604 slab_seq_start(struct seq_file
*f
, loff_t
*pos
)
610 down_read(&spl_kmem_cache_sem
);
612 slab_seq_show_headers(f
);
614 p
= spl_kmem_cache_list
.next
;
617 if (p
== &spl_kmem_cache_list
)
621 RETURN(list_entry(p
, spl_kmem_cache_t
, skc_list
));
625 slab_seq_next(struct seq_file
*f
, void *p
, loff_t
*pos
)
627 spl_kmem_cache_t
*skc
= p
;
631 RETURN((skc
->skc_list
.next
== &spl_kmem_cache_list
) ?
632 NULL
: list_entry(skc
->skc_list
.next
,spl_kmem_cache_t
,skc_list
));
636 slab_seq_stop(struct seq_file
*f
, void *v
)
638 up_read(&spl_kmem_cache_sem
);
641 static struct seq_operations slab_seq_ops
= {
642 .show
= slab_seq_show
,
643 .start
= slab_seq_start
,
644 .next
= slab_seq_next
,
645 .stop
= slab_seq_stop
,
649 proc_slab_open(struct inode
*inode
, struct file
*filp
)
651 return seq_open(filp
, &slab_seq_ops
);
654 static struct file_operations proc_slab_operations
= {
655 .open
= proc_slab_open
,
658 .release
= seq_release
,
660 #endif /* DEBUG_KMEM */
662 static struct ctl_table spl_debug_table
[] = {
664 .ctl_name
= CTL_DEBUG_SUBSYS
,
665 .procname
= "subsystem",
666 .data
= &spl_debug_subsys
,
667 .maxlen
= sizeof(unsigned long),
669 .proc_handler
= &proc_dobitmasks
672 .ctl_name
= CTL_DEBUG_MASK
,
674 .data
= &spl_debug_mask
,
675 .maxlen
= sizeof(unsigned long),
677 .proc_handler
= &proc_dobitmasks
680 .ctl_name
= CTL_DEBUG_PRINTK
,
681 .procname
= "printk",
682 .data
= &spl_debug_printk
,
683 .maxlen
= sizeof(unsigned long),
685 .proc_handler
= &proc_dobitmasks
688 .ctl_name
= CTL_DEBUG_MB
,
691 .proc_handler
= &proc_debug_mb
,
694 .ctl_name
= CTL_DEBUG_BINARY
,
695 .procname
= "binary",
696 .data
= &spl_debug_binary
,
697 .maxlen
= sizeof(int),
699 .proc_handler
= &proc_dointvec
,
702 .ctl_name
= CTL_DEBUG_CATASTROPHE
,
703 .procname
= "catastrophe",
704 .data
= &spl_debug_catastrophe
,
705 .maxlen
= sizeof(int),
707 .proc_handler
= &proc_dointvec
,
710 .ctl_name
= CTL_DEBUG_PANIC_ON_BUG
,
711 .procname
= "panic_on_bug",
712 .data
= &spl_debug_panic_on_bug
,
713 .maxlen
= sizeof(int),
715 .proc_handler
= &proc_dointvec
718 .ctl_name
= CTL_DEBUG_PATH
,
720 .data
= spl_debug_file_path
,
721 .maxlen
= sizeof(spl_debug_file_path
),
723 .proc_handler
= &proc_dostring
,
726 .ctl_name
= CTL_DEBUG_DUMP
,
729 .proc_handler
= &proc_dump_kernel
,
731 { .ctl_name
= CTL_DEBUG_FORCE_BUG
,
732 .procname
= "force_bug",
734 .proc_handler
= &proc_force_bug
,
737 .ctl_name
= CTL_CONSOLE_RATELIMIT
,
738 .procname
= "console_ratelimit",
739 .data
= &spl_console_ratelimit
,
740 .maxlen
= sizeof(int),
742 .proc_handler
= &proc_dointvec
,
745 .ctl_name
= CTL_CONSOLE_MAX_DELAY_CS
,
746 .procname
= "console_max_delay_centisecs",
747 .maxlen
= sizeof(int),
749 .proc_handler
= &proc_console_max_delay_cs
,
752 .ctl_name
= CTL_CONSOLE_MIN_DELAY_CS
,
753 .procname
= "console_min_delay_centisecs",
754 .maxlen
= sizeof(int),
756 .proc_handler
= &proc_console_min_delay_cs
,
759 .ctl_name
= CTL_CONSOLE_BACKOFF
,
760 .procname
= "console_backoff",
761 .maxlen
= sizeof(int),
763 .proc_handler
= &proc_console_backoff
,
766 .ctl_name
= CTL_DEBUG_STACK_SIZE
,
767 .procname
= "stack_max",
768 .data
= &spl_debug_stack
,
769 .maxlen
= sizeof(int),
771 .proc_handler
= &proc_dointvec
,
776 static struct ctl_table spl_vm_table
[] = {
778 .ctl_name
= CTL_VM_MINFREE
,
779 .procname
= "minfree",
781 .maxlen
= sizeof(int),
783 .proc_handler
= &proc_dointvec
,
786 .ctl_name
= CTL_VM_DESFREE
,
787 .procname
= "desfree",
789 .maxlen
= sizeof(int),
791 .proc_handler
= &proc_dointvec
,
794 .ctl_name
= CTL_VM_LOTSFREE
,
795 .procname
= "lotsfree",
797 .maxlen
= sizeof(int),
799 .proc_handler
= &proc_dointvec
,
802 .ctl_name
= CTL_VM_NEEDFREE
,
803 .procname
= "needfree",
805 .maxlen
= sizeof(int),
807 .proc_handler
= &proc_dointvec
,
810 .ctl_name
= CTL_VM_SWAPFS_MINFREE
,
811 .procname
= "swapfs_minfree",
812 .data
= &swapfs_minfree
,
813 .maxlen
= sizeof(int),
815 .proc_handler
= &proc_dointvec
,
818 .ctl_name
= CTL_VM_SWAPFS_RESERVE
,
819 .procname
= "swapfs_reserve",
820 .data
= &swapfs_reserve
,
821 .maxlen
= sizeof(int),
823 .proc_handler
= &proc_dointvec
,
826 .ctl_name
= CTL_VM_AVAILRMEM
,
827 .procname
= "availrmem",
829 .proc_handler
= &proc_doavailrmem
,
832 .ctl_name
= CTL_VM_FREEMEM
,
833 .procname
= "freemem",
835 .maxlen
= sizeof(int),
837 .proc_handler
= &proc_dofreemem
,
840 .ctl_name
= CTL_VM_PHYSMEM
,
841 .procname
= "physmem",
843 .maxlen
= sizeof(int),
845 .proc_handler
= &proc_dointvec
,
851 static struct ctl_table spl_kmem_table
[] = {
853 .ctl_name
= CTL_KMEM_KMEMUSED
,
854 .procname
= "kmem_used",
855 .data
= &kmem_alloc_used
,
856 # ifdef HAVE_ATOMIC64_T
857 .maxlen
= sizeof(atomic64_t
),
859 .maxlen
= sizeof(atomic_t
),
860 # endif /* HAVE_ATOMIC64_T */
862 .proc_handler
= &proc_domemused
,
865 .ctl_name
= CTL_KMEM_KMEMMAX
,
866 .procname
= "kmem_max",
867 .data
= &kmem_alloc_max
,
868 .maxlen
= sizeof(unsigned long),
869 .extra1
= &table_min
,
870 .extra2
= &table_max
,
872 .proc_handler
= &proc_doulongvec_minmax
,
875 .ctl_name
= CTL_KMEM_VMEMUSED
,
876 .procname
= "vmem_used",
877 .data
= &vmem_alloc_used
,
878 # ifdef HAVE_ATOMIC64_T
879 .maxlen
= sizeof(atomic64_t
),
881 .maxlen
= sizeof(atomic_t
),
882 # endif /* HAVE_ATOMIC64_T */
884 .proc_handler
= &proc_domemused
,
887 .ctl_name
= CTL_KMEM_VMEMMAX
,
888 .procname
= "vmem_max",
889 .data
= &vmem_alloc_max
,
890 .maxlen
= sizeof(unsigned long),
891 .extra1
= &table_min
,
892 .extra2
= &table_max
,
894 .proc_handler
= &proc_doulongvec_minmax
,
898 #endif /* DEBUG_KMEM */
900 static struct ctl_table spl_kstat_table
[] = {
904 static struct ctl_table spl_table
[] = {
905 /* NB No .strategy entries have been provided since
906 * sysctl(8) prefers to go via /proc for portability.
909 .ctl_name
= CTL_VERSION
,
910 .procname
= "version",
912 .maxlen
= sizeof(spl_version
),
914 .proc_handler
= &proc_dostring
,
917 .ctl_name
= CTL_HOSTID
,
918 .procname
= "hostid",
920 .maxlen
= sizeof(unsigned long),
922 .proc_handler
= &proc_dohostid
,
925 .ctl_name
= CTL_HW_SERIAL
,
926 .procname
= "hw_serial",
928 .maxlen
= sizeof(hw_serial
),
930 .proc_handler
= &proc_dostring
,
932 #ifndef HAVE_KALLSYMS_LOOKUP_NAME
934 .ctl_name
= CTL_KALLSYMS
,
935 .procname
= "kallsyms_lookup_name",
936 .data
= &spl_kallsyms_lookup_name_fn
,
937 .maxlen
= sizeof(unsigned long),
939 .proc_handler
= &proc_dokallsyms_lookup_name
,
943 .ctl_name
= CTL_SPL_DEBUG
,
946 .child
= spl_debug_table
,
949 .ctl_name
= CTL_SPL_VM
,
952 .child
= spl_vm_table
,
956 .ctl_name
= CTL_SPL_KMEM
,
959 .child
= spl_kmem_table
,
963 .ctl_name
= CTL_SPL_KSTAT
,
966 .child
= spl_kstat_table
,
971 static struct ctl_table spl_dir
[] = {
981 static struct ctl_table spl_root
[] = {
983 .ctl_name
= CTL_KERN
,
984 .procname
= "kernel",
992 proc_dir_entry_match(int len
, const char *name
, struct proc_dir_entry
*de
)
994 if (de
->namelen
!= len
)
997 return !memcmp(name
, de
->name
, len
);
1000 struct proc_dir_entry
*
1001 proc_dir_entry_find(struct proc_dir_entry
*root
, const char *str
)
1003 struct proc_dir_entry
*de
;
1005 for (de
= root
->subdir
; de
; de
= de
->next
)
1006 if (proc_dir_entry_match(strlen(str
), str
, de
))
1013 proc_dir_entries(struct proc_dir_entry
*root
)
1015 struct proc_dir_entry
*de
;
1018 for (de
= root
->subdir
; de
; de
= de
->next
)
1030 #ifdef CONFIG_SYSCTL
1031 spl_header
= spl_register_sysctl_table(spl_root
, 0);
1032 if (spl_header
== NULL
)
1034 #endif /* CONFIG_SYSCTL */
1036 proc_spl
= proc_mkdir("spl", NULL
);
1037 if (proc_spl
== NULL
)
1038 GOTO(out
, rc
= -EUNATCH
);
1041 proc_spl_kmem
= proc_mkdir("kmem", proc_spl
);
1042 if (proc_spl_kmem
== NULL
)
1043 GOTO(out
, rc
= -EUNATCH
);
1045 proc_spl_kmem_slab
= create_proc_entry("slab", 0444, proc_spl_kmem
);
1046 if (proc_spl_kmem_slab
== NULL
)
1047 GOTO(out
, rc
= -EUNATCH
);
1049 proc_spl_kmem_slab
->proc_fops
= &proc_slab_operations
;
1050 #endif /* DEBUG_KMEM */
1052 proc_spl_kstat
= proc_mkdir("kstat", proc_spl
);
1053 if (proc_spl_kstat
== NULL
)
1054 GOTO(out
, rc
= -EUNATCH
);
1057 remove_proc_entry("kstat", proc_spl
);
1059 remove_proc_entry("slab", proc_spl_kmem
);
1060 remove_proc_entry("kmem", proc_spl
);
1062 remove_proc_entry("spl", NULL
);
1063 #ifdef CONFIG_SYSCTL
1064 spl_unregister_sysctl_table(spl_header
);
1065 #endif /* CONFIG_SYSCTL */
1076 remove_proc_entry("kstat", proc_spl
);
1078 remove_proc_entry("slab", proc_spl_kmem
);
1079 remove_proc_entry("kmem", proc_spl
);
1081 remove_proc_entry("spl", NULL
);
1083 #ifdef CONFIG_SYSCTL
1084 ASSERT(spl_header
!= NULL
);
1085 spl_unregister_sysctl_table(spl_header
);
1086 #endif /* CONFIG_SYSCTL */