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://zfsonlinux.org/>.
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>
32 #include <linux/version.h>
33 #include <spl-debug.h>
35 #ifdef SS_DEBUG_SUBSYS
36 #undef SS_DEBUG_SUBSYS
39 #define SS_DEBUG_SUBSYS SS_PROC
41 #if defined(CONSTIFY_PLUGIN) && LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
42 typedef struct ctl_table __no_const spl_ctl_table
;
44 typedef struct ctl_table spl_ctl_table
;
48 static unsigned long table_min
= 0;
49 static unsigned long table_max
= ~0;
52 static struct ctl_table_header
*spl_header
= NULL
;
53 static struct proc_dir_entry
*proc_spl
= NULL
;
55 static struct proc_dir_entry
*proc_spl_kmem
= NULL
;
56 static struct proc_dir_entry
*proc_spl_kmem_slab
= NULL
;
57 #endif /* DEBUG_KMEM */
58 struct proc_dir_entry
*proc_spl_kstat
= NULL
;
61 proc_copyin_string(char *kbuffer
, int kbuffer_size
,
62 const char *ubuffer
, int ubuffer_size
)
66 if (ubuffer_size
> kbuffer_size
)
69 if (copy_from_user((void *)kbuffer
, (void *)ubuffer
, ubuffer_size
))
72 /* strip trailing whitespace */
73 size
= strnlen(kbuffer
, ubuffer_size
);
75 if (!isspace(kbuffer
[size
]))
82 /* no space to terminate */
83 if (size
== kbuffer_size
)
86 kbuffer
[size
+ 1] = 0;
91 proc_copyout_string(char *ubuffer
, int ubuffer_size
,
92 const char *kbuffer
, char *append
)
94 /* NB if 'append' != NULL, it's a single character to append to the
95 * copied out string - usually "\n", for /proc entries and
96 * (i.e. a terminating zero byte) for sysctl entries
98 int size
= MIN(strlen(kbuffer
), ubuffer_size
);
100 if (copy_to_user(ubuffer
, kbuffer
, size
))
103 if (append
!= NULL
&& size
< ubuffer_size
) {
104 if (copy_to_user(ubuffer
+ size
, append
, 1))
114 SPL_PROC_HANDLER(proc_dobitmasks
)
116 unsigned long *mask
= table
->data
;
117 int is_subsys
= (mask
== &spl_debug_subsys
) ? 1 : 0;
118 int is_printk
= (mask
== &spl_debug_printk
) ? 1 : 0;
123 str
= kmem_alloc(size
, KM_SLEEP
);
128 rc
= proc_copyin_string(str
, size
, buffer
, *lenp
);
132 rc
= spl_debug_str2mask(mask
, str
, is_subsys
);
133 /* Always print BUG/ASSERT to console, so keep this mask */
139 rc
= spl_debug_mask2str(str
, size
, *mask
, is_subsys
);
143 rc
= proc_copyout_string(buffer
, *lenp
,
151 kmem_free(str
, size
);
155 SPL_PROC_HANDLER(proc_debug_mb
)
162 rc
= proc_copyin_string(str
, sizeof(str
), buffer
, *lenp
);
166 rc
= spl_debug_set_mb(simple_strtoul(str
, NULL
, 0));
169 len
= snprintf(str
, sizeof(str
), "%d", spl_debug_get_mb());
173 rc
= proc_copyout_string(buffer
,*lenp
,str
+*ppos
,"\n");
184 SPL_PROC_HANDLER(proc_dump_kernel
)
189 spl_debug_dumplog(0);
198 SPL_PROC_HANDLER(proc_force_bug
)
203 PANIC("Crashing due to forced panic\n");
210 SPL_PROC_HANDLER(proc_console_max_delay_cs
)
212 int rc
, max_delay_cs
;
213 spl_ctl_table dummy
= *table
;
217 dummy
.data
= &max_delay_cs
;
218 dummy
.proc_handler
= &proc_dointvec
;
222 rc
= spl_proc_dointvec(&dummy
,write
,filp
,buffer
,lenp
,ppos
);
226 if (max_delay_cs
<= 0)
229 d
= (max_delay_cs
* HZ
) / 100;
230 if (d
== 0 || d
< spl_console_min_delay
)
233 spl_console_max_delay
= d
;
235 max_delay_cs
= (spl_console_max_delay
* 100) / HZ
;
236 rc
= spl_proc_dointvec(&dummy
,write
,filp
,buffer
,lenp
,ppos
);
242 SPL_PROC_HANDLER(proc_console_min_delay_cs
)
244 int rc
, min_delay_cs
;
245 spl_ctl_table dummy
= *table
;
249 dummy
.data
= &min_delay_cs
;
250 dummy
.proc_handler
= &proc_dointvec
;
254 rc
= spl_proc_dointvec(&dummy
,write
,filp
,buffer
,lenp
,ppos
);
258 if (min_delay_cs
<= 0)
261 d
= (min_delay_cs
* HZ
) / 100;
262 if (d
== 0 || d
> spl_console_max_delay
)
265 spl_console_min_delay
= d
;
267 min_delay_cs
= (spl_console_min_delay
* 100) / HZ
;
268 rc
= spl_proc_dointvec(&dummy
,write
,filp
,buffer
,lenp
,ppos
);
274 SPL_PROC_HANDLER(proc_console_backoff
)
277 spl_ctl_table dummy
= *table
;
280 dummy
.data
= &backoff
;
281 dummy
.proc_handler
= &proc_dointvec
;
285 rc
= spl_proc_dointvec(&dummy
,write
,filp
,buffer
,lenp
,ppos
);
292 spl_console_backoff
= backoff
;
294 backoff
= spl_console_backoff
;
295 rc
= spl_proc_dointvec(&dummy
,write
,filp
,buffer
,lenp
,ppos
);
300 #endif /* DEBUG_LOG */
303 SPL_PROC_HANDLER(proc_domemused
)
306 unsigned long min
= 0, max
= ~0, val
;
307 spl_ctl_table dummy
= *table
;
311 dummy
.proc_handler
= &proc_dointvec
;
318 # ifdef HAVE_ATOMIC64_T
319 val
= atomic64_read((atomic64_t
*)table
->data
);
321 val
= atomic_read((atomic_t
*)table
->data
);
322 # endif /* HAVE_ATOMIC64_T */
323 rc
= spl_proc_doulongvec_minmax(&dummy
, write
, filp
,
330 SPL_PROC_HANDLER(proc_doslab
)
333 unsigned long min
= 0, max
= ~0, val
= 0, mask
;
334 spl_ctl_table dummy
= *table
;
335 spl_kmem_cache_t
*skc
;
339 dummy
.proc_handler
= &proc_dointvec
;
346 down_read(&spl_kmem_cache_sem
);
347 mask
= (unsigned long)table
->data
;
349 list_for_each_entry(skc
, &spl_kmem_cache_list
, skc_list
) {
351 /* Only use slabs of the correct kmem/vmem type */
352 if (!(skc
->skc_flags
& mask
))
355 /* Sum the specified field for selected slabs */
356 switch (mask
& (KMC_TOTAL
| KMC_ALLOC
| KMC_MAX
)) {
358 val
+= skc
->skc_slab_size
* skc
->skc_slab_total
;
361 val
+= skc
->skc_obj_size
* skc
->skc_obj_alloc
;
364 val
+= skc
->skc_obj_size
* skc
->skc_obj_max
;
369 up_read(&spl_kmem_cache_sem
);
370 rc
= spl_proc_doulongvec_minmax(&dummy
, write
, filp
,
376 #endif /* DEBUG_KMEM */
378 SPL_PROC_HANDLER(proc_dohostid
)
385 /* We can't use spl_proc_doulongvec_minmax() in the write
386 * case here because hostid while a hex value has no
387 * leading 0x which confuses the helper function. */
388 rc
= proc_copyin_string(str
, sizeof(str
), buffer
, *lenp
);
392 spl_hostid
= simple_strtoul(str
, &end
, 16);
397 len
= snprintf(str
, sizeof(str
), "%lx", spl_hostid
);
401 rc
= proc_copyout_string(buffer
,*lenp
,str
+*ppos
,"\n");
414 slab_seq_show_headers(struct seq_file
*f
)
417 "--------------------- cache ----------"
418 "--------------------------------------------- "
421 "--- emergency ---\n");
424 " flags size alloc slabsize objsize "
427 "dlock alloc max\n");
431 slab_seq_show(struct seq_file
*f
, void *p
)
433 spl_kmem_cache_t
*skc
= p
;
435 ASSERT(skc
->skc_magic
== SKC_MAGIC
);
438 * Backed by Linux slab see /proc/slabinfo.
440 if (skc
->skc_flags
& KMC_SLAB
)
443 spin_lock(&skc
->skc_lock
);
444 seq_printf(f
, "%-36s ", skc
->skc_name
);
445 seq_printf(f
, "0x%05lx %9lu %9lu %8u %8u "
446 "%5lu %5lu %5lu %5lu %5lu %5lu %5lu %5lu %5lu\n",
447 (long unsigned)skc
->skc_flags
,
448 (long unsigned)(skc
->skc_slab_size
* skc
->skc_slab_total
),
449 (long unsigned)(skc
->skc_obj_size
* skc
->skc_obj_alloc
),
450 (unsigned)skc
->skc_slab_size
,
451 (unsigned)skc
->skc_obj_size
,
452 (long unsigned)skc
->skc_slab_total
,
453 (long unsigned)skc
->skc_slab_alloc
,
454 (long unsigned)skc
->skc_slab_max
,
455 (long unsigned)skc
->skc_obj_total
,
456 (long unsigned)skc
->skc_obj_alloc
,
457 (long unsigned)skc
->skc_obj_max
,
458 (long unsigned)skc
->skc_obj_deadlock
,
459 (long unsigned)skc
->skc_obj_emergency
,
460 (long unsigned)skc
->skc_obj_emergency_max
);
462 spin_unlock(&skc
->skc_lock
);
468 slab_seq_start(struct seq_file
*f
, loff_t
*pos
)
474 down_read(&spl_kmem_cache_sem
);
476 slab_seq_show_headers(f
);
478 p
= spl_kmem_cache_list
.next
;
481 if (p
== &spl_kmem_cache_list
)
485 SRETURN(list_entry(p
, spl_kmem_cache_t
, skc_list
));
489 slab_seq_next(struct seq_file
*f
, void *p
, loff_t
*pos
)
491 spl_kmem_cache_t
*skc
= p
;
495 SRETURN((skc
->skc_list
.next
== &spl_kmem_cache_list
) ?
496 NULL
: list_entry(skc
->skc_list
.next
,spl_kmem_cache_t
,skc_list
));
500 slab_seq_stop(struct seq_file
*f
, void *v
)
502 up_read(&spl_kmem_cache_sem
);
505 static struct seq_operations slab_seq_ops
= {
506 .show
= slab_seq_show
,
507 .start
= slab_seq_start
,
508 .next
= slab_seq_next
,
509 .stop
= slab_seq_stop
,
513 proc_slab_open(struct inode
*inode
, struct file
*filp
)
515 return seq_open(filp
, &slab_seq_ops
);
518 static struct file_operations proc_slab_operations
= {
519 .open
= proc_slab_open
,
522 .release
= seq_release
,
524 #endif /* DEBUG_KMEM */
527 static struct ctl_table spl_debug_table
[] = {
529 .procname
= "subsystem",
530 .data
= &spl_debug_subsys
,
531 .maxlen
= sizeof(unsigned long),
533 .proc_handler
= &proc_dobitmasks
537 .data
= &spl_debug_mask
,
538 .maxlen
= sizeof(unsigned long),
540 .proc_handler
= &proc_dobitmasks
543 .procname
= "printk",
544 .data
= &spl_debug_printk
,
545 .maxlen
= sizeof(unsigned long),
547 .proc_handler
= &proc_dobitmasks
552 .proc_handler
= &proc_debug_mb
,
555 .procname
= "binary",
556 .data
= &spl_debug_binary
,
557 .maxlen
= sizeof(int),
559 .proc_handler
= &proc_dointvec
,
562 .procname
= "catastrophe",
563 .data
= &spl_debug_catastrophe
,
564 .maxlen
= sizeof(int),
566 .proc_handler
= &proc_dointvec
,
569 .procname
= "panic_on_bug",
570 .data
= &spl_debug_panic_on_bug
,
571 .maxlen
= sizeof(int),
573 .proc_handler
= &proc_dointvec
577 .data
= spl_debug_file_path
,
578 .maxlen
= sizeof(spl_debug_file_path
),
580 .proc_handler
= &proc_dostring
,
585 .proc_handler
= &proc_dump_kernel
,
588 .procname
= "force_bug",
590 .proc_handler
= &proc_force_bug
,
593 .procname
= "console_ratelimit",
594 .data
= &spl_console_ratelimit
,
595 .maxlen
= sizeof(int),
597 .proc_handler
= &proc_dointvec
,
600 .procname
= "console_max_delay_centisecs",
601 .maxlen
= sizeof(int),
603 .proc_handler
= &proc_console_max_delay_cs
,
606 .procname
= "console_min_delay_centisecs",
607 .maxlen
= sizeof(int),
609 .proc_handler
= &proc_console_min_delay_cs
,
612 .procname
= "console_backoff",
613 .maxlen
= sizeof(int),
615 .proc_handler
= &proc_console_backoff
,
618 .procname
= "stack_max",
619 .data
= &spl_debug_stack
,
620 .maxlen
= sizeof(int),
622 .proc_handler
= &proc_dointvec
,
626 #endif /* DEBUG_LOG */
629 static struct ctl_table spl_kmem_table
[] = {
631 .procname
= "kmem_used",
632 .data
= &kmem_alloc_used
,
633 # ifdef HAVE_ATOMIC64_T
634 .maxlen
= sizeof(atomic64_t
),
636 .maxlen
= sizeof(atomic_t
),
637 # endif /* HAVE_ATOMIC64_T */
639 .proc_handler
= &proc_domemused
,
642 .procname
= "kmem_max",
643 .data
= &kmem_alloc_max
,
644 .maxlen
= sizeof(unsigned long),
645 .extra1
= &table_min
,
646 .extra2
= &table_max
,
648 .proc_handler
= &proc_doulongvec_minmax
,
651 .procname
= "vmem_used",
652 .data
= &vmem_alloc_used
,
653 # ifdef HAVE_ATOMIC64_T
654 .maxlen
= sizeof(atomic64_t
),
656 .maxlen
= sizeof(atomic_t
),
657 # endif /* HAVE_ATOMIC64_T */
659 .proc_handler
= &proc_domemused
,
662 .procname
= "vmem_max",
663 .data
= &vmem_alloc_max
,
664 .maxlen
= sizeof(unsigned long),
665 .extra1
= &table_min
,
666 .extra2
= &table_max
,
668 .proc_handler
= &proc_doulongvec_minmax
,
671 .procname
= "slab_kmem_total",
672 .data
= (void *)(KMC_KMEM
| KMC_TOTAL
),
673 .maxlen
= sizeof(unsigned long),
674 .extra1
= &table_min
,
675 .extra2
= &table_max
,
677 .proc_handler
= &proc_doslab
,
680 .procname
= "slab_kmem_alloc",
681 .data
= (void *)(KMC_KMEM
| KMC_ALLOC
),
682 .maxlen
= sizeof(unsigned long),
683 .extra1
= &table_min
,
684 .extra2
= &table_max
,
686 .proc_handler
= &proc_doslab
,
689 .procname
= "slab_kmem_max",
690 .data
= (void *)(KMC_KMEM
| KMC_MAX
),
691 .maxlen
= sizeof(unsigned long),
692 .extra1
= &table_min
,
693 .extra2
= &table_max
,
695 .proc_handler
= &proc_doslab
,
698 .procname
= "slab_vmem_total",
699 .data
= (void *)(KMC_VMEM
| KMC_TOTAL
),
700 .maxlen
= sizeof(unsigned long),
701 .extra1
= &table_min
,
702 .extra2
= &table_max
,
704 .proc_handler
= &proc_doslab
,
707 .procname
= "slab_vmem_alloc",
708 .data
= (void *)(KMC_VMEM
| KMC_ALLOC
),
709 .maxlen
= sizeof(unsigned long),
710 .extra1
= &table_min
,
711 .extra2
= &table_max
,
713 .proc_handler
= &proc_doslab
,
716 .procname
= "slab_vmem_max",
717 .data
= (void *)(KMC_VMEM
| KMC_MAX
),
718 .maxlen
= sizeof(unsigned long),
719 .extra1
= &table_min
,
720 .extra2
= &table_max
,
722 .proc_handler
= &proc_doslab
,
726 #endif /* DEBUG_KMEM */
728 static struct ctl_table spl_kstat_table
[] = {
732 static struct ctl_table spl_table
[] = {
733 /* NB No .strategy entries have been provided since
734 * sysctl(8) prefers to go via /proc for portability.
737 .procname
= "version",
739 .maxlen
= sizeof(spl_version
),
741 .proc_handler
= &proc_dostring
,
744 .procname
= "hostid",
746 .maxlen
= sizeof(unsigned long),
748 .proc_handler
= &proc_dohostid
,
754 .child
= spl_debug_table
,
761 .child
= spl_kmem_table
,
767 .child
= spl_kstat_table
,
772 static struct ctl_table spl_dir
[] = {
781 static struct ctl_table spl_root
[] = {
784 .ctl_name
= CTL_KERN
,
786 .procname
= "kernel",
799 spl_header
= register_sysctl_table(spl_root
);
800 if (spl_header
== NULL
)
803 proc_spl
= proc_mkdir("spl", NULL
);
804 if (proc_spl
== NULL
)
805 SGOTO(out
, rc
= -EUNATCH
);
808 proc_spl_kmem
= proc_mkdir("kmem", proc_spl
);
809 if (proc_spl_kmem
== NULL
)
810 SGOTO(out
, rc
= -EUNATCH
);
812 proc_spl_kmem_slab
= proc_create_data("slab", 0444,
813 proc_spl_kmem
, &proc_slab_operations
, NULL
);
814 if (proc_spl_kmem_slab
== NULL
)
815 SGOTO(out
, rc
= -EUNATCH
);
817 #endif /* DEBUG_KMEM */
819 proc_spl_kstat
= proc_mkdir("kstat", proc_spl
);
820 if (proc_spl_kstat
== NULL
)
821 SGOTO(out
, rc
= -EUNATCH
);
824 remove_proc_entry("kstat", proc_spl
);
826 remove_proc_entry("slab", proc_spl_kmem
);
827 remove_proc_entry("kmem", proc_spl
);
829 remove_proc_entry("spl", NULL
);
830 unregister_sysctl_table(spl_header
);
841 remove_proc_entry("kstat", proc_spl
);
843 remove_proc_entry("slab", proc_spl_kmem
);
844 remove_proc_entry("kmem", proc_spl
);
846 remove_proc_entry("spl", NULL
);
848 ASSERT(spl_header
!= NULL
);
849 unregister_sysctl_table(spl_header
);