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 static struct proc_dir_entry
*proc_spl
= NULL
;
46 static struct proc_dir_entry
*proc_spl_kmem
= NULL
;
47 static struct proc_dir_entry
*proc_spl_kmem_slab
= NULL
;
48 #endif /* DEBUG_KMEM */
49 struct proc_dir_entry
*proc_spl_kstat
= NULL
;
51 #ifdef HAVE_CTL_UNNUMBERED
53 #define CTL_SPL CTL_UNNUMBERED
54 #define CTL_SPL_DEBUG CTL_UNNUMBERED
55 #define CTL_SPL_VM CTL_UNNUMBERED
56 #define CTL_SPL_MUTEX CTL_UNNUMBERED
57 #define CTL_SPL_KMEM CTL_UNNUMBERED
58 #define CTL_SPL_KSTAT CTL_UNNUMBERED
60 #define CTL_VERSION CTL_UNNUMBERED /* Version */
61 #define CTL_HOSTID CTL_UNNUMBERED /* Host id by /usr/bin/hostid */
62 #define CTL_HW_SERIAL CTL_UNNUMBERED /* HW serial number by hostid */
63 #define CTL_KALLSYMS CTL_UNNUMBERED /* kallsyms_lookup_name addr */
65 #define CTL_DEBUG_SUBSYS CTL_UNNUMBERED /* Debug subsystem */
66 #define CTL_DEBUG_MASK CTL_UNNUMBERED /* Debug mask */
67 #define CTL_DEBUG_PRINTK CTL_UNNUMBERED /* All messages to console */
68 #define CTL_DEBUG_MB CTL_UNNUMBERED /* Debug buffer size */
69 #define CTL_DEBUG_BINARY CTL_UNNUMBERED /* Binary data in buffer */
70 #define CTL_DEBUG_CATASTROPHE CTL_UNNUMBERED /* Set if BUG'd or panic'd */
71 #define CTL_DEBUG_PANIC_ON_BUG CTL_UNNUMBERED /* Should panic on BUG */
72 #define CTL_DEBUG_PATH CTL_UNNUMBERED /* Dump log location */
73 #define CTL_DEBUG_DUMP CTL_UNNUMBERED /* Dump debug buffer to file */
74 #define CTL_DEBUG_FORCE_BUG CTL_UNNUMBERED /* Hook to force a BUG */
75 #define CTL_DEBUG_STACK_SIZE CTL_UNNUMBERED /* Max observed stack size */
77 #define CTL_CONSOLE_RATELIMIT CTL_UNNUMBERED /* Ratelimit console messages */
78 #define CTL_CONSOLE_MAX_DELAY_CS CTL_UNNUMBERED /* Max delay skip messages */
79 #define CTL_CONSOLE_MIN_DELAY_CS CTL_UNNUMBERED /* Init delay skip messages */
80 #define CTL_CONSOLE_BACKOFF CTL_UNNUMBERED /* Delay increase factor */
82 #define CTL_VM_MINFREE CTL_UNNUMBERED /* Minimum free memory */
83 #define CTL_VM_DESFREE CTL_UNNUMBERED /* Desired free memory */
84 #define CTL_VM_LOTSFREE CTL_UNNUMBERED /* Lots of free memory */
85 #define CTL_VM_NEEDFREE CTL_UNNUMBERED /* Need free memory */
86 #define CTL_VM_SWAPFS_MINFREE CTL_UNNUMBERED /* Minimum swapfs memory */
87 #define CTL_VM_SWAPFS_RESERVE CTL_UNNUMBERED /* Reserved swapfs memory */
88 #define CTL_VM_AVAILRMEM CTL_UNNUMBERED /* Easily available memory */
89 #define CTL_VM_FREEMEM CTL_UNNUMBERED /* Free memory */
90 #define CTL_VM_PHYSMEM CTL_UNNUMBERED /* Total physical memory */
93 #define CTL_KMEM_KMEMUSED CTL_UNNUMBERED /* Alloc'd kmem bytes */
94 #define CTL_KMEM_KMEMMAX CTL_UNNUMBERED /* Max alloc'd by kmem bytes */
95 #define CTL_KMEM_VMEMUSED CTL_UNNUMBERED /* Alloc'd vmem bytes */
96 #define CTL_KMEM_VMEMMAX CTL_UNNUMBERED /* Max alloc'd by vmem bytes */
97 #define CTL_KMEM_ALLOC_FAILED CTL_UNNUMBERED /* Cache allocations failed */
100 #else /* HAVE_CTL_UNNUMBERED */
104 CTL_SPL_DEBUG
= 0x88,
106 CTL_SPL_MUTEX
= 0x90,
108 CTL_SPL_KSTAT
= 0x92,
112 CTL_VERSION
= 1, /* Version */
113 CTL_HOSTID
, /* Host id reported by /usr/bin/hostid */
114 CTL_HW_SERIAL
, /* Hardware serial number from hostid */
115 CTL_KALLSYMS
, /* Address of kallsyms_lookup_name */
117 CTL_DEBUG_SUBSYS
, /* Debug subsystem */
118 CTL_DEBUG_MASK
, /* Debug mask */
119 CTL_DEBUG_PRINTK
, /* Force all messages to console */
120 CTL_DEBUG_MB
, /* Debug buffer size */
121 CTL_DEBUG_BINARY
, /* Include binary data in buffer */
122 CTL_DEBUG_CATASTROPHE
, /* Set if we have BUG'd or panic'd */
123 CTL_DEBUG_PANIC_ON_BUG
, /* Set if we should panic on BUG */
124 CTL_DEBUG_PATH
, /* Dump log location */
125 CTL_DEBUG_DUMP
, /* Dump debug buffer to file */
126 CTL_DEBUG_FORCE_BUG
, /* Hook to force a BUG */
127 CTL_DEBUG_STACK_SIZE
, /* Max observed stack size */
129 CTL_CONSOLE_RATELIMIT
, /* Ratelimit console messages */
130 CTL_CONSOLE_MAX_DELAY_CS
, /* Max delay which we skip messages */
131 CTL_CONSOLE_MIN_DELAY_CS
, /* Init delay which we skip messages */
132 CTL_CONSOLE_BACKOFF
, /* Delay increase factor */
134 CTL_VM_MINFREE
, /* Minimum free memory threshold */
135 CTL_VM_DESFREE
, /* Desired free memory threshold */
136 CTL_VM_LOTSFREE
, /* Lots of free memory threshold */
137 CTL_VM_NEEDFREE
, /* Need free memory deficit */
138 CTL_VM_SWAPFS_MINFREE
, /* Minimum swapfs memory */
139 CTL_VM_SWAPFS_RESERVE
, /* Reserved swapfs memory */
140 CTL_VM_AVAILRMEM
, /* Easily available memory */
141 CTL_VM_FREEMEM
, /* Free memory */
142 CTL_VM_PHYSMEM
, /* Total physical memory */
145 CTL_KMEM_KMEMUSED
, /* Alloc'd kmem bytes */
146 CTL_KMEM_KMEMMAX
, /* Max alloc'd by kmem bytes */
147 CTL_KMEM_VMEMUSED
, /* Alloc'd vmem bytes */
148 CTL_KMEM_VMEMMAX
, /* Max alloc'd by vmem bytes */
151 #endif /* HAVE_CTL_UNNUMBERED */
154 proc_copyin_string(char *kbuffer
, int kbuffer_size
,
155 const char *ubuffer
, int ubuffer_size
)
159 if (ubuffer_size
> kbuffer_size
)
162 if (copy_from_user((void *)kbuffer
, (void *)ubuffer
, ubuffer_size
))
165 /* strip trailing whitespace */
166 size
= strnlen(kbuffer
, ubuffer_size
);
168 if (!isspace(kbuffer
[size
]))
175 /* no space to terminate */
176 if (size
== kbuffer_size
)
179 kbuffer
[size
+ 1] = 0;
184 proc_copyout_string(char *ubuffer
, int ubuffer_size
,
185 const char *kbuffer
, char *append
)
187 /* NB if 'append' != NULL, it's a single character to append to the
188 * copied out string - usually "\n", for /proc entries and
189 * (i.e. a terminating zero byte) for sysctl entries
191 int size
= MIN(strlen(kbuffer
), ubuffer_size
);
193 if (copy_to_user(ubuffer
, kbuffer
, size
))
196 if (append
!= NULL
&& size
< ubuffer_size
) {
197 if (copy_to_user(ubuffer
+ size
, append
, 1))
207 proc_dobitmasks(struct ctl_table
*table
, int write
, struct file
*filp
,
208 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
210 unsigned long *mask
= table
->data
;
211 int is_subsys
= (mask
== &spl_debug_subsys
) ? 1 : 0;
212 int is_printk
= (mask
== &spl_debug_printk
) ? 1 : 0;
217 str
= kmem_alloc(size
, KM_SLEEP
);
222 rc
= proc_copyin_string(str
, size
, buffer
, *lenp
);
226 rc
= spl_debug_str2mask(mask
, str
, is_subsys
);
227 /* Always print BUG/ASSERT to console, so keep this mask */
233 rc
= spl_debug_mask2str(str
, size
, *mask
, is_subsys
);
237 rc
= proc_copyout_string(buffer
, *lenp
,
245 kmem_free(str
, size
);
250 proc_debug_mb(struct ctl_table
*table
, int write
, struct file
*filp
,
251 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
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");
281 proc_dump_kernel(struct ctl_table
*table
, int write
, struct file
*filp
,
282 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
287 spl_debug_dumplog(0);
297 proc_force_bug(struct ctl_table
*table
, int write
, struct file
*filp
,
298 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
303 CERROR("Crashing due to forced SBUG\n");
314 proc_console_max_delay_cs(struct ctl_table
*table
, int write
, struct file
*filp
,
315 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
317 int rc
, max_delay_cs
;
318 struct ctl_table dummy
= *table
;
322 dummy
.data
= &max_delay_cs
;
323 dummy
.proc_handler
= &proc_dointvec
;
327 rc
= proc_dointvec(&dummy
, write
, filp
, buffer
, lenp
, ppos
);
331 if (max_delay_cs
<= 0)
334 d
= (max_delay_cs
* HZ
) / 100;
335 if (d
== 0 || d
< spl_console_min_delay
)
338 spl_console_max_delay
= d
;
340 max_delay_cs
= (spl_console_max_delay
* 100) / HZ
;
341 rc
= proc_dointvec(&dummy
, write
, filp
, buffer
, lenp
, ppos
);
348 proc_console_min_delay_cs(struct ctl_table
*table
, int write
, struct file
*filp
,
349 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
351 int rc
, min_delay_cs
;
352 struct ctl_table dummy
= *table
;
356 dummy
.data
= &min_delay_cs
;
357 dummy
.proc_handler
= &proc_dointvec
;
361 rc
= proc_dointvec(&dummy
, write
, filp
, buffer
, lenp
, ppos
);
365 if (min_delay_cs
<= 0)
368 d
= (min_delay_cs
* HZ
) / 100;
369 if (d
== 0 || d
> spl_console_max_delay
)
372 spl_console_min_delay
= d
;
374 min_delay_cs
= (spl_console_min_delay
* 100) / HZ
;
375 rc
= proc_dointvec(&dummy
, write
, filp
, buffer
, lenp
, ppos
);
382 proc_console_backoff(struct ctl_table
*table
, int write
, struct file
*filp
,
383 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
386 struct ctl_table dummy
= *table
;
389 dummy
.data
= &backoff
;
390 dummy
.proc_handler
= &proc_dointvec
;
394 rc
= proc_dointvec(&dummy
, write
, filp
, buffer
, lenp
, ppos
);
401 spl_console_backoff
= backoff
;
403 backoff
= spl_console_backoff
;
404 rc
= proc_dointvec(&dummy
, write
, filp
, buffer
, lenp
, ppos
);
412 proc_domemused(struct ctl_table
*table
, int write
, struct file
*filp
,
413 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
416 unsigned long min
= 0, max
= ~0, val
;
417 struct ctl_table dummy
= *table
;
421 dummy
.proc_handler
= &proc_dointvec
;
428 # ifdef HAVE_ATOMIC64_T
429 val
= atomic64_read((atomic64_t
*)table
->data
);
431 val
= atomic_read((atomic_t
*)table
->data
);
432 # endif /* HAVE_ATOMIC64_T */
433 rc
= proc_doulongvec_minmax(&dummy
, write
, filp
,
439 #endif /* DEBUG_KMEM */
442 proc_dohostid(struct ctl_table
*table
, int write
, struct file
*filp
,
443 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
451 /* We can't use proc_doulongvec_minmax() in the write
452 * case hear because hostid while a hex value has no
453 * leading 0x which confuses the helper function. */
454 rc
= proc_copyin_string(str
, sizeof(str
), buffer
, *lenp
);
458 val
= simple_strtol(str
, &end
, 16);
462 spl_hostid
= (long) val
;
463 (void) snprintf(hw_serial
, HW_HOSTID_LEN
, "%u",
464 (val
>= 0) ? val
: -val
);
465 hw_serial
[HW_HOSTID_LEN
- 1] = '\0';
468 len
= snprintf(str
, sizeof(str
), "%lx", spl_hostid
);
472 rc
= proc_copyout_string(buffer
, *lenp
, str
+ *ppos
, "\n");
483 #ifndef HAVE_KALLSYMS_LOOKUP_NAME
485 proc_dokallsyms_lookup_name(struct ctl_table
*table
, int write
,
486 struct file
*filp
, void __user
*buffer
,
487 size_t *lenp
, loff_t
*ppos
) {
493 /* This may only be set once at module load time */
494 if (spl_kallsyms_lookup_name_fn
!= SYMBOL_POISON
)
497 /* We can't use proc_doulongvec_minmax() in the write
498 * case hear because the address while a hex value has no
499 * leading 0x which confuses the helper function. */
500 rc
= proc_copyin_string(str
, sizeof(str
), buffer
, *lenp
);
504 spl_kallsyms_lookup_name_fn
=
505 (kallsyms_lookup_name_t
)simple_strtoul(str
, &end
, 16);
511 len
= snprintf(str
, sizeof(str
), "%lx",
512 (unsigned long)spl_kallsyms_lookup_name_fn
);
516 rc
= proc_copyout_string(buffer
,*lenp
,str
+*ppos
,"\n");
526 #endif /* HAVE_KALLSYMS_LOOKUP_NAME */
529 proc_doavailrmem(struct ctl_table
*table
, int write
, struct file
*filp
,
530 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
539 len
= snprintf(str
, sizeof(str
), "%lu", (unsigned long)availrmem
);
543 rc
= proc_copyout_string(buffer
, *lenp
, str
+ *ppos
, "\n");
555 proc_dofreemem(struct ctl_table
*table
, int write
, struct file
*filp
,
556 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
565 len
= snprintf(str
, sizeof(str
), "%lu", (unsigned long)freemem
);
569 rc
= proc_copyout_string(buffer
, *lenp
, str
+ *ppos
, "\n");
582 slab_seq_show_headers(struct seq_file
*f
)
584 seq_printf(f
, "%-36s\n", "name");
588 slab_seq_show(struct seq_file
*f
, void *p
)
590 spl_kmem_cache_t
*skc
= p
;
592 ASSERT(skc
->skc_magic
== SKC_MAGIC
);
594 spin_lock(&skc
->skc_lock
);
595 seq_printf(f
, "%-36s ", skc
->skc_name
);
596 seq_printf(f
, "%u %u %u - %lu %lu %lu - %lu %lu %lu - %lu %lu %lu\n",
597 (unsigned)skc
->skc_obj_size
,
598 (unsigned)skc
->skc_slab_objs
,
599 (unsigned)skc
->skc_slab_size
,
600 (long unsigned)skc
->skc_slab_fail
,
601 (long unsigned)skc
->skc_slab_create
,
602 (long unsigned)skc
->skc_slab_destroy
,
603 (long unsigned)skc
->skc_slab_total
,
604 (long unsigned)skc
->skc_slab_alloc
,
605 (long unsigned)skc
->skc_slab_max
,
606 (long unsigned)skc
->skc_obj_total
,
607 (long unsigned)skc
->skc_obj_alloc
,
608 (long unsigned)skc
->skc_obj_max
);
610 spin_unlock(&skc
->skc_lock
);
616 slab_seq_start(struct seq_file
*f
, loff_t
*pos
)
622 down_read(&spl_kmem_cache_sem
);
624 slab_seq_show_headers(f
);
626 p
= spl_kmem_cache_list
.next
;
629 if (p
== &spl_kmem_cache_list
)
633 RETURN(list_entry(p
, spl_kmem_cache_t
, skc_list
));
637 slab_seq_next(struct seq_file
*f
, void *p
, loff_t
*pos
)
639 spl_kmem_cache_t
*skc
= p
;
643 RETURN((skc
->skc_list
.next
== &spl_kmem_cache_list
) ?
644 NULL
: list_entry(skc
->skc_list
.next
, spl_kmem_cache_t
, skc_list
));
648 slab_seq_stop(struct seq_file
*f
, void *v
)
650 up_read(&spl_kmem_cache_sem
);
653 static struct seq_operations slab_seq_ops
= {
654 .show
= slab_seq_show
,
655 .start
= slab_seq_start
,
656 .next
= slab_seq_next
,
657 .stop
= slab_seq_stop
,
661 proc_slab_open(struct inode
*inode
, struct file
*filp
)
663 return seq_open(filp
, &slab_seq_ops
);
666 static struct file_operations proc_slab_operations
= {
667 .open
= proc_slab_open
,
670 .release
= seq_release
,
672 #endif /* DEBUG_KMEM */
674 static struct ctl_table spl_debug_table
[] = {
676 .ctl_name
= CTL_DEBUG_SUBSYS
,
677 .procname
= "subsystem",
678 .data
= &spl_debug_subsys
,
679 .maxlen
= sizeof(unsigned long),
681 .proc_handler
= &proc_dobitmasks
684 .ctl_name
= CTL_DEBUG_MASK
,
686 .data
= &spl_debug_mask
,
687 .maxlen
= sizeof(unsigned long),
689 .proc_handler
= &proc_dobitmasks
692 .ctl_name
= CTL_DEBUG_PRINTK
,
693 .procname
= "printk",
694 .data
= &spl_debug_printk
,
695 .maxlen
= sizeof(unsigned long),
697 .proc_handler
= &proc_dobitmasks
700 .ctl_name
= CTL_DEBUG_MB
,
703 .proc_handler
= &proc_debug_mb
,
706 .ctl_name
= CTL_DEBUG_BINARY
,
707 .procname
= "binary",
708 .data
= &spl_debug_binary
,
709 .maxlen
= sizeof(int),
711 .proc_handler
= &proc_dointvec
,
714 .ctl_name
= CTL_DEBUG_CATASTROPHE
,
715 .procname
= "catastrophe",
716 .data
= &spl_debug_catastrophe
,
717 .maxlen
= sizeof(int),
719 .proc_handler
= &proc_dointvec
,
722 .ctl_name
= CTL_DEBUG_PANIC_ON_BUG
,
723 .procname
= "panic_on_bug",
724 .data
= &spl_debug_panic_on_bug
,
725 .maxlen
= sizeof(int),
727 .proc_handler
= &proc_dointvec
730 .ctl_name
= CTL_DEBUG_PATH
,
732 .data
= spl_debug_file_path
,
733 .maxlen
= sizeof(spl_debug_file_path
),
735 .proc_handler
= &proc_dostring
,
738 .ctl_name
= CTL_DEBUG_DUMP
,
741 .proc_handler
= &proc_dump_kernel
,
743 { .ctl_name
= CTL_DEBUG_FORCE_BUG
,
744 .procname
= "force_bug",
746 .proc_handler
= &proc_force_bug
,
749 .ctl_name
= CTL_CONSOLE_RATELIMIT
,
750 .procname
= "console_ratelimit",
751 .data
= &spl_console_ratelimit
,
752 .maxlen
= sizeof(int),
754 .proc_handler
= &proc_dointvec
,
757 .ctl_name
= CTL_CONSOLE_MAX_DELAY_CS
,
758 .procname
= "console_max_delay_centisecs",
759 .maxlen
= sizeof(int),
761 .proc_handler
= &proc_console_max_delay_cs
,
764 .ctl_name
= CTL_CONSOLE_MIN_DELAY_CS
,
765 .procname
= "console_min_delay_centisecs",
766 .maxlen
= sizeof(int),
768 .proc_handler
= &proc_console_min_delay_cs
,
771 .ctl_name
= CTL_CONSOLE_BACKOFF
,
772 .procname
= "console_backoff",
773 .maxlen
= sizeof(int),
775 .proc_handler
= &proc_console_backoff
,
778 .ctl_name
= CTL_DEBUG_STACK_SIZE
,
779 .procname
= "stack_max",
780 .data
= &spl_debug_stack
,
781 .maxlen
= sizeof(int),
783 .proc_handler
= &proc_dointvec
,
788 static struct ctl_table spl_vm_table
[] = {
790 .ctl_name
= CTL_VM_MINFREE
,
791 .procname
= "minfree",
793 .maxlen
= sizeof(int),
795 .proc_handler
= &proc_dointvec
,
798 .ctl_name
= CTL_VM_DESFREE
,
799 .procname
= "desfree",
801 .maxlen
= sizeof(int),
803 .proc_handler
= &proc_dointvec
,
806 .ctl_name
= CTL_VM_LOTSFREE
,
807 .procname
= "lotsfree",
809 .maxlen
= sizeof(int),
811 .proc_handler
= &proc_dointvec
,
814 .ctl_name
= CTL_VM_NEEDFREE
,
815 .procname
= "needfree",
817 .maxlen
= sizeof(int),
819 .proc_handler
= &proc_dointvec
,
822 .ctl_name
= CTL_VM_SWAPFS_MINFREE
,
823 .procname
= "swapfs_minfree",
824 .data
= &swapfs_minfree
,
825 .maxlen
= sizeof(int),
827 .proc_handler
= &proc_dointvec
,
830 .ctl_name
= CTL_VM_SWAPFS_RESERVE
,
831 .procname
= "swapfs_reserve",
832 .data
= &swapfs_reserve
,
833 .maxlen
= sizeof(int),
835 .proc_handler
= &proc_dointvec
,
838 .ctl_name
= CTL_VM_AVAILRMEM
,
839 .procname
= "availrmem",
841 .proc_handler
= &proc_doavailrmem
,
844 .ctl_name
= CTL_VM_FREEMEM
,
845 .procname
= "freemem",
847 .maxlen
= sizeof(int),
849 .proc_handler
= &proc_dofreemem
,
852 .ctl_name
= CTL_VM_PHYSMEM
,
853 .procname
= "physmem",
855 .maxlen
= sizeof(int),
857 .proc_handler
= &proc_dointvec
,
863 static struct ctl_table spl_kmem_table
[] = {
865 .ctl_name
= CTL_KMEM_KMEMUSED
,
866 .procname
= "kmem_used",
867 .data
= &kmem_alloc_used
,
868 # ifdef HAVE_ATOMIC64_T
869 .maxlen
= sizeof(atomic64_t
),
871 .maxlen
= sizeof(atomic_t
),
872 # endif /* HAVE_ATOMIC64_T */
874 .proc_handler
= &proc_domemused
,
877 .ctl_name
= CTL_KMEM_KMEMMAX
,
878 .procname
= "kmem_max",
879 .data
= &kmem_alloc_max
,
880 .maxlen
= sizeof(unsigned long),
881 .extra1
= &table_min
,
882 .extra2
= &table_max
,
884 .proc_handler
= &proc_doulongvec_minmax
,
887 .ctl_name
= CTL_KMEM_VMEMUSED
,
888 .procname
= "vmem_used",
889 .data
= &vmem_alloc_used
,
890 # ifdef HAVE_ATOMIC64_T
891 .maxlen
= sizeof(atomic64_t
),
893 .maxlen
= sizeof(atomic_t
),
894 # endif /* HAVE_ATOMIC64_T */
896 .proc_handler
= &proc_domemused
,
899 .ctl_name
= CTL_KMEM_VMEMMAX
,
900 .procname
= "vmem_max",
901 .data
= &vmem_alloc_max
,
902 .maxlen
= sizeof(unsigned long),
903 .extra1
= &table_min
,
904 .extra2
= &table_max
,
906 .proc_handler
= &proc_doulongvec_minmax
,
910 #endif /* DEBUG_KMEM */
912 static struct ctl_table spl_kstat_table
[] = {
916 static struct ctl_table spl_table
[] = {
917 /* NB No .strategy entries have been provided since
918 * sysctl(8) prefers to go via /proc for portability.
921 .ctl_name
= CTL_VERSION
,
922 .procname
= "version",
924 .maxlen
= sizeof(spl_version
),
926 .proc_handler
= &proc_dostring
,
929 .ctl_name
= CTL_HOSTID
,
930 .procname
= "hostid",
932 .maxlen
= sizeof(unsigned long),
934 .proc_handler
= &proc_dohostid
,
937 .ctl_name
= CTL_HW_SERIAL
,
938 .procname
= "hw_serial",
940 .maxlen
= sizeof(hw_serial
),
942 .proc_handler
= &proc_dostring
,
944 #ifndef HAVE_KALLSYMS_LOOKUP_NAME
946 .ctl_name
= CTL_KALLSYMS
,
947 .procname
= "kallsyms_lookup_name",
948 .data
= &spl_kallsyms_lookup_name_fn
,
949 .maxlen
= sizeof(unsigned long),
951 .proc_handler
= &proc_dokallsyms_lookup_name
,
955 .ctl_name
= CTL_SPL_DEBUG
,
958 .child
= spl_debug_table
,
961 .ctl_name
= CTL_SPL_VM
,
964 .child
= spl_vm_table
,
968 .ctl_name
= CTL_SPL_KMEM
,
971 .child
= spl_kmem_table
,
975 .ctl_name
= CTL_SPL_KSTAT
,
978 .child
= spl_kstat_table
,
983 static struct ctl_table spl_dir
[] = {
993 static struct ctl_table spl_root
[] = {
995 .ctl_name
= CTL_KERN
,
996 .procname
= "kernel",
1004 proc_dir_entry_match(int len
, const char *name
, struct proc_dir_entry
*de
)
1006 if (de
->namelen
!= len
)
1009 return !memcmp(name
, de
->name
, len
);
1012 struct proc_dir_entry
*
1013 proc_dir_entry_find(struct proc_dir_entry
*root
, const char *str
)
1015 struct proc_dir_entry
*de
;
1017 for (de
= root
->subdir
; de
; de
= de
->next
)
1018 if (proc_dir_entry_match(strlen(str
), str
, de
))
1025 proc_dir_entries(struct proc_dir_entry
*root
)
1027 struct proc_dir_entry
*de
;
1030 for (de
= root
->subdir
; de
; de
= de
->next
)
1042 #ifdef CONFIG_SYSCTL
1043 spl_header
= spl_register_sysctl_table(spl_root
, 0);
1044 if (spl_header
== NULL
)
1046 #endif /* CONFIG_SYSCTL */
1048 proc_spl
= proc_mkdir("spl", NULL
);
1049 if (proc_spl
== NULL
)
1050 GOTO(out
, rc
= -EUNATCH
);
1053 proc_spl_kmem
= proc_mkdir("kmem", proc_spl
);
1054 if (proc_spl_kmem
== NULL
)
1055 GOTO(out
, rc
= -EUNATCH
);
1057 proc_spl_kmem_slab
= create_proc_entry("slab", 0444, proc_spl_kmem
);
1058 if (proc_spl_kmem_slab
== NULL
)
1059 GOTO(out
, rc
= -EUNATCH
);
1061 proc_spl_kmem_slab
->proc_fops
= &proc_slab_operations
;
1062 #endif /* DEBUG_KMEM */
1064 proc_spl_kstat
= proc_mkdir("kstat", proc_spl
);
1065 if (proc_spl_kstat
== NULL
)
1066 GOTO(out
, rc
= -EUNATCH
);
1069 remove_proc_entry("kstat", proc_spl
);
1071 remove_proc_entry("slab", proc_spl_kmem
);
1072 remove_proc_entry("kmem", proc_spl
);
1074 remove_proc_entry("spl", NULL
);
1075 #ifdef CONFIG_SYSCTL
1076 spl_unregister_sysctl_table(spl_header
);
1077 #endif /* CONFIG_SYSCTL */
1088 remove_proc_entry("kstat", proc_spl
);
1090 remove_proc_entry("slab", proc_spl_kmem
);
1091 remove_proc_entry("kmem", proc_spl
);
1093 remove_proc_entry("spl", NULL
);
1095 #ifdef CONFIG_SYSCTL
1096 ASSERT(spl_header
!= NULL
);
1097 spl_unregister_sysctl_table(spl_header
);
1098 #endif /* CONFIG_SYSCTL */