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) Kstat Implementation.
25 \*****************************************************************************/
27 #include <linux/seq_file.h>
28 #include <sys/kstat.h>
29 #include <spl-debug.h>
31 #ifdef SS_DEBUG_SUBSYS
32 #undef SS_DEBUG_SUBSYS
35 #define SS_DEBUG_SUBSYS SS_KSTAT
37 #define PDE_DATA(x) (PDE(x)->data)
40 static kmutex_t kstat_module_lock
;
41 static struct list_head kstat_module_list
;
42 static kid_t kstat_id
;
45 kstat_seq_show_headers(struct seq_file
*f
)
47 kstat_t
*ksp
= (kstat_t
*)f
->private;
48 ASSERT(ksp
->ks_magic
== KS_MAGIC
);
50 seq_printf(f
, "%d %d 0x%02x %d %d %lld %lld\n",
51 ksp
->ks_kid
, ksp
->ks_type
, ksp
->ks_flags
,
52 ksp
->ks_ndata
, (int)ksp
->ks_data_size
,
53 ksp
->ks_crtime
, ksp
->ks_snaptime
);
55 switch (ksp
->ks_type
) {
57 seq_printf(f
, "raw data");
59 case KSTAT_TYPE_NAMED
:
60 seq_printf(f
, "%-31s %-4s %s\n",
61 "name", "type", "data");
64 seq_printf(f
, "%-8s %-8s %-8s %-8s %-8s\n",
65 "hard", "soft", "watchdog",
66 "spurious", "multsvc");
70 "%-8s %-8s %-8s %-8s %-8s %-8s "
71 "%-8s %-8s %-8s %-8s %-8s %-8s\n",
72 "nread", "nwritten", "reads", "writes",
73 "wtime", "wlentime", "wupdate",
74 "rtime", "rlentime", "rupdate",
77 case KSTAT_TYPE_TIMER
:
80 "%-8s %-8s %-8s %-8s %-8s\n",
81 "name", "events", "elapsed",
82 "min", "max", "start", "stop");
86 "%-8s %-5s %-13s %-12s %-12s %-8s %-8s "
87 "%-12s %-12s %-12s\n",
88 "txg", "state", "birth",
89 "nread", "nwritten", "reads", "writes",
90 "otime", "qtime", "stime");
93 PANIC("Undefined kstat type %d\n", ksp
->ks_type
);
98 kstat_seq_show_raw(struct seq_file
*f
, unsigned char *p
, int l
)
103 seq_printf(f
, "%03x:", i
);
105 for (j
= 0; j
< 16; j
++) {
106 if (i
* 16 + j
>= l
) {
111 seq_printf(f
, " %02x", (unsigned char)p
[i
* 16 + j
]);
120 kstat_seq_show_named(struct seq_file
*f
, kstat_named_t
*knp
)
122 seq_printf(f
, "%-31s %-4d ", knp
->name
, knp
->data_type
);
124 switch (knp
->data_type
) {
125 case KSTAT_DATA_CHAR
:
126 knp
->value
.c
[15] = '\0'; /* NULL terminate */
127 seq_printf(f
, "%-16s", knp
->value
.c
);
129 /* XXX - We need to be more careful able what tokens are
130 * used for each arch, for now this is correct for x86_64.
132 case KSTAT_DATA_INT32
:
133 seq_printf(f
, "%d", knp
->value
.i32
);
135 case KSTAT_DATA_UINT32
:
136 seq_printf(f
, "%u", knp
->value
.ui32
);
138 case KSTAT_DATA_INT64
:
139 seq_printf(f
, "%lld", (signed long long)knp
->value
.i64
);
141 case KSTAT_DATA_UINT64
:
142 seq_printf(f
, "%llu", (unsigned long long)knp
->value
.ui64
);
144 case KSTAT_DATA_LONG
:
145 seq_printf(f
, "%ld", knp
->value
.l
);
147 case KSTAT_DATA_ULONG
:
148 seq_printf(f
, "%lu", knp
->value
.ul
);
150 case KSTAT_DATA_STRING
:
151 KSTAT_NAMED_STR_PTR(knp
)
152 [KSTAT_NAMED_STR_BUFLEN(knp
)-1] = '\0';
153 seq_printf(f
, "%s", KSTAT_NAMED_STR_PTR(knp
));
156 PANIC("Undefined kstat data type %d\n", knp
->data_type
);
165 kstat_seq_show_intr(struct seq_file
*f
, kstat_intr_t
*kip
)
167 seq_printf(f
, "%-8u %-8u %-8u %-8u %-8u\n",
168 kip
->intrs
[KSTAT_INTR_HARD
],
169 kip
->intrs
[KSTAT_INTR_SOFT
],
170 kip
->intrs
[KSTAT_INTR_WATCHDOG
],
171 kip
->intrs
[KSTAT_INTR_SPURIOUS
],
172 kip
->intrs
[KSTAT_INTR_MULTSVC
]);
178 kstat_seq_show_io(struct seq_file
*f
, kstat_io_t
*kip
)
181 "%-8llu %-8llu %-8u %-8u %-8lld %-8lld "
182 "%-8lld %-8lld %-8lld %-8lld %-8u %-8u\n",
183 kip
->nread
, kip
->nwritten
,
184 kip
->reads
, kip
->writes
,
185 kip
->wtime
, kip
->wlentime
, kip
->wlastupdate
,
186 kip
->rtime
, kip
->wlentime
, kip
->rlastupdate
,
187 kip
->wcnt
, kip
->rcnt
);
193 kstat_seq_show_timer(struct seq_file
*f
, kstat_timer_t
*ktp
)
196 "%-31s %-8llu %-8lld %-8lld %-8lld %-8lld %-8lld\n",
197 ktp
->name
, ktp
->num_events
, ktp
->elapsed_time
,
198 ktp
->min_time
, ktp
->max_time
,
199 ktp
->start_time
, ktp
->stop_time
);
205 kstat_seq_show_txg(struct seq_file
*f
, kstat_txg_t
*ktp
)
209 switch (ktp
->state
) {
210 case TXG_STATE_OPEN
: state
= 'O'; break;
211 case TXG_STATE_QUIESCING
: state
= 'Q'; break;
212 case TXG_STATE_SYNCING
: state
= 'S'; break;
213 case TXG_STATE_COMMITTED
: state
= 'C'; break;
214 default: state
= '?'; break;
218 "%-8llu %-5c %-13llu %-12llu %-12llu %-8u %-8u "
219 "%12lld %12lld %12lld\n", ktp
->txg
, state
, ktp
->birth
,
220 ktp
->nread
, ktp
->nwritten
, ktp
->reads
, ktp
->writes
,
221 ktp
->open_time
, ktp
->quiesce_time
, ktp
->sync_time
);
226 kstat_seq_show(struct seq_file
*f
, void *p
)
228 kstat_t
*ksp
= (kstat_t
*)f
->private;
231 ASSERT(ksp
->ks_magic
== KS_MAGIC
);
233 switch (ksp
->ks_type
) {
235 ASSERT(ksp
->ks_ndata
== 1);
236 rc
= kstat_seq_show_raw(f
, ksp
->ks_data
,
239 case KSTAT_TYPE_NAMED
:
240 rc
= kstat_seq_show_named(f
, (kstat_named_t
*)p
);
242 case KSTAT_TYPE_INTR
:
243 rc
= kstat_seq_show_intr(f
, (kstat_intr_t
*)p
);
246 rc
= kstat_seq_show_io(f
, (kstat_io_t
*)p
);
248 case KSTAT_TYPE_TIMER
:
249 rc
= kstat_seq_show_timer(f
, (kstat_timer_t
*)p
);
252 rc
= kstat_seq_show_txg(f
, (kstat_txg_t
*)p
);
255 PANIC("Undefined kstat type %d\n", ksp
->ks_type
);
262 kstat_default_update(kstat_t
*ksp
, int rw
)
269 kstat_seq_data_addr(kstat_t
*ksp
, loff_t n
)
274 switch (ksp
->ks_type
) {
278 case KSTAT_TYPE_NAMED
:
279 rc
= ksp
->ks_data
+ n
* sizeof(kstat_named_t
);
281 case KSTAT_TYPE_INTR
:
282 rc
= ksp
->ks_data
+ n
* sizeof(kstat_intr_t
);
285 rc
= ksp
->ks_data
+ n
* sizeof(kstat_io_t
);
287 case KSTAT_TYPE_TIMER
:
288 rc
= ksp
->ks_data
+ n
* sizeof(kstat_timer_t
);
291 rc
= ksp
->ks_data
+ n
* sizeof(kstat_txg_t
);
294 PANIC("Undefined kstat type %d\n", ksp
->ks_type
);
301 kstat_seq_start(struct seq_file
*f
, loff_t
*pos
)
304 kstat_t
*ksp
= (kstat_t
*)f
->private;
305 ASSERT(ksp
->ks_magic
== KS_MAGIC
);
308 mutex_enter(&ksp
->ks_lock
);
310 /* Dynamically update kstat, on error existing kstats are used */
311 (void) ksp
->ks_update(ksp
, KSTAT_READ
);
313 ksp
->ks_snaptime
= gethrtime();
316 kstat_seq_show_headers(f
);
318 if (n
>= ksp
->ks_ndata
)
321 SRETURN(kstat_seq_data_addr(ksp
, n
));
325 kstat_seq_next(struct seq_file
*f
, void *p
, loff_t
*pos
)
327 kstat_t
*ksp
= (kstat_t
*)f
->private;
328 ASSERT(ksp
->ks_magic
== KS_MAGIC
);
332 if (*pos
>= ksp
->ks_ndata
)
335 SRETURN(kstat_seq_data_addr(ksp
, *pos
));
339 kstat_seq_stop(struct seq_file
*f
, void *v
)
341 kstat_t
*ksp
= (kstat_t
*)f
->private;
342 ASSERT(ksp
->ks_magic
== KS_MAGIC
);
344 mutex_exit(&ksp
->ks_lock
);
347 static struct seq_operations kstat_seq_ops
= {
348 .show
= kstat_seq_show
,
349 .start
= kstat_seq_start
,
350 .next
= kstat_seq_next
,
351 .stop
= kstat_seq_stop
,
354 static kstat_module_t
*
355 kstat_find_module(char *name
)
357 kstat_module_t
*module
;
359 list_for_each_entry(module
, &kstat_module_list
, ksm_module_list
)
360 if (strncmp(name
, module
->ksm_name
, KSTAT_STRLEN
) == 0)
366 static kstat_module_t
*
367 kstat_create_module(char *name
)
369 kstat_module_t
*module
;
370 struct proc_dir_entry
*pde
;
372 pde
= proc_mkdir(name
, proc_spl_kstat
);
376 module
= kmem_alloc(sizeof (kstat_module_t
), KM_SLEEP
);
377 module
->ksm_proc
= pde
;
378 strlcpy(module
->ksm_name
, name
, KSTAT_STRLEN
+1);
379 INIT_LIST_HEAD(&module
->ksm_kstat_list
);
380 list_add_tail(&module
->ksm_module_list
, &kstat_module_list
);
387 kstat_delete_module(kstat_module_t
*module
)
389 ASSERT(list_empty(&module
->ksm_kstat_list
));
390 remove_proc_entry(module
->ksm_name
, proc_spl_kstat
);
391 list_del(&module
->ksm_module_list
);
392 kmem_free(module
, sizeof(kstat_module_t
));
396 proc_kstat_open(struct inode
*inode
, struct file
*filp
)
401 rc
= seq_open(filp
, &kstat_seq_ops
);
405 f
= filp
->private_data
;
406 f
->private = PDE_DATA(inode
);
411 static struct file_operations proc_kstat_operations
= {
412 .open
= proc_kstat_open
,
415 .release
= seq_release
,
419 __kstat_create(const char *ks_module
, int ks_instance
, const char *ks_name
,
420 const char *ks_class
, uchar_t ks_type
, uint_t ks_ndata
,
426 ASSERT(ks_instance
== 0);
428 ASSERT(!(ks_flags
& KSTAT_FLAG_UNSUPPORTED
));
430 if ((ks_type
== KSTAT_TYPE_INTR
) || (ks_type
== KSTAT_TYPE_IO
))
431 ASSERT(ks_ndata
== 1);
433 ksp
= kmem_zalloc(sizeof(*ksp
), KM_SLEEP
);
437 mutex_enter(&kstat_module_lock
);
438 ksp
->ks_kid
= kstat_id
;
440 mutex_exit(&kstat_module_lock
);
442 ksp
->ks_magic
= KS_MAGIC
;
443 mutex_init(&ksp
->ks_lock
, NULL
, MUTEX_DEFAULT
, NULL
);
444 INIT_LIST_HEAD(&ksp
->ks_list
);
446 ksp
->ks_crtime
= gethrtime();
447 ksp
->ks_snaptime
= ksp
->ks_crtime
;
448 strncpy(ksp
->ks_module
, ks_module
, KSTAT_STRLEN
);
449 ksp
->ks_instance
= ks_instance
;
450 strncpy(ksp
->ks_name
, ks_name
, KSTAT_STRLEN
);
451 strncpy(ksp
->ks_class
, ks_class
, KSTAT_STRLEN
);
452 ksp
->ks_type
= ks_type
;
453 ksp
->ks_flags
= ks_flags
;
454 ksp
->ks_update
= kstat_default_update
;
455 ksp
->ks_private
= NULL
;
457 switch (ksp
->ks_type
) {
460 ksp
->ks_data_size
= ks_ndata
;
462 case KSTAT_TYPE_NAMED
:
463 ksp
->ks_ndata
= ks_ndata
;
464 ksp
->ks_data_size
= ks_ndata
* sizeof(kstat_named_t
);
466 case KSTAT_TYPE_INTR
:
467 ksp
->ks_ndata
= ks_ndata
;
468 ksp
->ks_data_size
= ks_ndata
* sizeof(kstat_intr_t
);
471 ksp
->ks_ndata
= ks_ndata
;
472 ksp
->ks_data_size
= ks_ndata
* sizeof(kstat_io_t
);
474 case KSTAT_TYPE_TIMER
:
475 ksp
->ks_ndata
= ks_ndata
;
476 ksp
->ks_data_size
= ks_ndata
* sizeof(kstat_timer_t
);
479 ksp
->ks_ndata
= ks_ndata
;
480 ksp
->ks_data_size
= ks_ndata
* sizeof(kstat_timer_t
);
483 PANIC("Undefined kstat type %d\n", ksp
->ks_type
);
486 if (ksp
->ks_flags
& KSTAT_FLAG_VIRTUAL
) {
489 ksp
->ks_data
= kmem_alloc(ksp
->ks_data_size
, KM_SLEEP
);
490 if (ksp
->ks_data
== NULL
) {
491 kmem_free(ksp
, sizeof(*ksp
));
498 EXPORT_SYMBOL(__kstat_create
);
501 __kstat_install(kstat_t
*ksp
)
503 kstat_module_t
*module
;
508 mutex_enter(&kstat_module_lock
);
510 module
= kstat_find_module(ksp
->ks_module
);
511 if (module
== NULL
) {
512 module
= kstat_create_module(ksp
->ks_module
);
518 * Only one entry by this name per-module, on failure the module
519 * shouldn't be deleted because we know it has at least one entry.
521 list_for_each_entry(tmp
, &module
->ksm_kstat_list
, ks_list
)
522 if (strncmp(tmp
->ks_name
, ksp
->ks_name
, KSTAT_STRLEN
) == 0)
525 list_add_tail(&ksp
->ks_list
, &module
->ksm_kstat_list
);
527 mutex_enter(&ksp
->ks_lock
);
528 ksp
->ks_owner
= module
;
529 ksp
->ks_proc
= proc_create_data(ksp
->ks_name
, 0444,
530 module
->ksm_proc
, &proc_kstat_operations
, (void *)ksp
);
531 if (ksp
->ks_proc
== NULL
) {
532 list_del_init(&ksp
->ks_list
);
533 if (list_empty(&module
->ksm_kstat_list
))
534 kstat_delete_module(module
);
536 mutex_exit(&ksp
->ks_lock
);
538 mutex_exit(&kstat_module_lock
);
540 EXPORT_SYMBOL(__kstat_install
);
543 __kstat_delete(kstat_t
*ksp
)
545 kstat_module_t
*module
= ksp
->ks_owner
;
547 mutex_enter(&kstat_module_lock
);
548 list_del_init(&ksp
->ks_list
);
549 mutex_exit(&kstat_module_lock
);
552 remove_proc_entry(ksp
->ks_name
, module
->ksm_proc
);
554 /* Remove top level module directory if it's empty */
555 if (list_empty(&module
->ksm_kstat_list
))
556 kstat_delete_module(module
);
559 if (!(ksp
->ks_flags
& KSTAT_FLAG_VIRTUAL
))
560 kmem_free(ksp
->ks_data
, ksp
->ks_data_size
);
562 mutex_destroy(&ksp
->ks_lock
);
563 kmem_free(ksp
, sizeof(*ksp
));
567 EXPORT_SYMBOL(__kstat_delete
);
573 mutex_init(&kstat_module_lock
, NULL
, MUTEX_DEFAULT
, NULL
);
574 INIT_LIST_HEAD(&kstat_module_list
);
583 ASSERT(list_empty(&kstat_module_list
));
584 mutex_destroy(&kstat_module_lock
);