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) 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 static spinlock_t kstat_lock
;
38 static struct list_head kstat_list
;
39 static kid_t kstat_id
;
42 kstat_seq_show_headers(struct seq_file
*f
)
44 kstat_t
*ksp
= (kstat_t
*)f
->private;
45 ASSERT(ksp
->ks_magic
== KS_MAGIC
);
47 seq_printf(f
, "%d %d 0x%02x %d %d %lld %lld\n",
48 ksp
->ks_kid
, ksp
->ks_type
, ksp
->ks_flags
,
49 ksp
->ks_ndata
, (int)ksp
->ks_data_size
,
50 ksp
->ks_crtime
, ksp
->ks_snaptime
);
52 switch (ksp
->ks_type
) {
54 seq_printf(f
, "raw data");
56 case KSTAT_TYPE_NAMED
:
57 seq_printf(f
, "%-31s %-4s %s\n",
58 "name", "type", "data");
61 seq_printf(f
, "%-8s %-8s %-8s %-8s %-8s\n",
62 "hard", "soft", "watchdog",
63 "spurious", "multsvc");
67 "%-8s %-8s %-8s %-8s %-8s %-8s "
68 "%-8s %-8s %-8s %-8s %-8s %-8s\n",
69 "nread", "nwritten", "reads", "writes",
70 "wtime", "wlentime", "wupdate",
71 "rtime", "rlentime", "rupdate",
74 case KSTAT_TYPE_TIMER
:
77 "%-8s %-8s %-8s %-8s %-8s\n",
78 "name", "events", "elapsed",
79 "min", "max", "start", "stop");
82 PANIC("Undefined kstat type %d\n", ksp
->ks_type
);
87 kstat_seq_show_raw(struct seq_file
*f
, unsigned char *p
, int l
)
92 seq_printf(f
, "%03x:", i
);
94 for (j
= 0; j
< 16; j
++) {
95 if (i
* 16 + j
>= l
) {
100 seq_printf(f
, " %02x", (unsigned char)p
[i
* 16 + j
]);
109 kstat_seq_show_named(struct seq_file
*f
, kstat_named_t
*knp
)
111 seq_printf(f
, "%-31s %-4d ", knp
->name
, knp
->data_type
);
113 switch (knp
->data_type
) {
114 case KSTAT_DATA_CHAR
:
115 knp
->value
.c
[15] = '\0'; /* NULL terminate */
116 seq_printf(f
, "%-16s", knp
->value
.c
);
118 /* XXX - We need to be more careful able what tokens are
119 * used for each arch, for now this is correct for x86_64.
121 case KSTAT_DATA_INT32
:
122 seq_printf(f
, "%d", knp
->value
.i32
);
124 case KSTAT_DATA_UINT32
:
125 seq_printf(f
, "%u", knp
->value
.ui32
);
127 case KSTAT_DATA_INT64
:
128 seq_printf(f
, "%lld", (signed long long)knp
->value
.i64
);
130 case KSTAT_DATA_UINT64
:
131 seq_printf(f
, "%llu", (unsigned long long)knp
->value
.ui64
);
133 case KSTAT_DATA_LONG
:
134 seq_printf(f
, "%ld", knp
->value
.l
);
136 case KSTAT_DATA_ULONG
:
137 seq_printf(f
, "%lu", knp
->value
.ul
);
139 case KSTAT_DATA_STRING
:
140 KSTAT_NAMED_STR_PTR(knp
)
141 [KSTAT_NAMED_STR_BUFLEN(knp
)-1] = '\0';
142 seq_printf(f
, "%s", KSTAT_NAMED_STR_PTR(knp
));
145 PANIC("Undefined kstat data type %d\n", knp
->data_type
);
154 kstat_seq_show_intr(struct seq_file
*f
, kstat_intr_t
*kip
)
156 seq_printf(f
, "%-8u %-8u %-8u %-8u %-8u\n",
157 kip
->intrs
[KSTAT_INTR_HARD
],
158 kip
->intrs
[KSTAT_INTR_SOFT
],
159 kip
->intrs
[KSTAT_INTR_WATCHDOG
],
160 kip
->intrs
[KSTAT_INTR_SPURIOUS
],
161 kip
->intrs
[KSTAT_INTR_MULTSVC
]);
167 kstat_seq_show_io(struct seq_file
*f
, kstat_io_t
*kip
)
170 "%-8llu %-8llu %-8u %-8u %-8lld %-8lld "
171 "%-8lld %-8lld %-8lld %-8lld %-8u %-8u\n",
172 kip
->nread
, kip
->nwritten
,
173 kip
->reads
, kip
->writes
,
174 kip
->wtime
, kip
->wlentime
, kip
->wlastupdate
,
175 kip
->rtime
, kip
->wlentime
, kip
->rlastupdate
,
176 kip
->wcnt
, kip
->rcnt
);
182 kstat_seq_show_timer(struct seq_file
*f
, kstat_timer_t
*ktp
)
185 "%-31s %-8llu %-8lld %-8lld %-8lld %-8lld %-8lld\n",
186 ktp
->name
, ktp
->num_events
, ktp
->elapsed_time
,
187 ktp
->min_time
, ktp
->max_time
,
188 ktp
->start_time
, ktp
->stop_time
);
194 kstat_seq_show(struct seq_file
*f
, void *p
)
196 kstat_t
*ksp
= (kstat_t
*)f
->private;
199 ASSERT(ksp
->ks_magic
== KS_MAGIC
);
201 switch (ksp
->ks_type
) {
203 ASSERT(ksp
->ks_ndata
== 1);
204 rc
= kstat_seq_show_raw(f
, ksp
->ks_data
,
207 case KSTAT_TYPE_NAMED
:
208 rc
= kstat_seq_show_named(f
, (kstat_named_t
*)p
);
210 case KSTAT_TYPE_INTR
:
211 rc
= kstat_seq_show_intr(f
, (kstat_intr_t
*)p
);
214 rc
= kstat_seq_show_io(f
, (kstat_io_t
*)p
);
216 case KSTAT_TYPE_TIMER
:
217 rc
= kstat_seq_show_timer(f
, (kstat_timer_t
*)p
);
220 PANIC("Undefined kstat type %d\n", ksp
->ks_type
);
227 kstat_default_update(kstat_t
*ksp
, int rw
)
234 kstat_seq_data_addr(kstat_t
*ksp
, loff_t n
)
239 switch (ksp
->ks_type
) {
243 case KSTAT_TYPE_NAMED
:
244 rc
= ksp
->ks_data
+ n
* sizeof(kstat_named_t
);
246 case KSTAT_TYPE_INTR
:
247 rc
= ksp
->ks_data
+ n
* sizeof(kstat_intr_t
);
250 rc
= ksp
->ks_data
+ n
* sizeof(kstat_io_t
);
252 case KSTAT_TYPE_TIMER
:
253 rc
= ksp
->ks_data
+ n
* sizeof(kstat_timer_t
);
256 PANIC("Undefined kstat type %d\n", ksp
->ks_type
);
263 kstat_seq_start(struct seq_file
*f
, loff_t
*pos
)
266 kstat_t
*ksp
= (kstat_t
*)f
->private;
267 ASSERT(ksp
->ks_magic
== KS_MAGIC
);
270 mutex_enter(&ksp
->ks_lock
);
272 /* Dynamically update kstat, on error existing kstats are used */
273 (void) ksp
->ks_update(ksp
, KSTAT_READ
);
275 ksp
->ks_snaptime
= gethrtime();
278 kstat_seq_show_headers(f
);
280 if (n
>= ksp
->ks_ndata
)
283 SRETURN(kstat_seq_data_addr(ksp
, n
));
287 kstat_seq_next(struct seq_file
*f
, void *p
, loff_t
*pos
)
289 kstat_t
*ksp
= (kstat_t
*)f
->private;
290 ASSERT(ksp
->ks_magic
== KS_MAGIC
);
294 if (*pos
>= ksp
->ks_ndata
)
297 SRETURN(kstat_seq_data_addr(ksp
, *pos
));
301 kstat_seq_stop(struct seq_file
*f
, void *v
)
303 kstat_t
*ksp
= (kstat_t
*)f
->private;
304 ASSERT(ksp
->ks_magic
== KS_MAGIC
);
306 mutex_exit(&ksp
->ks_lock
);
309 static struct seq_operations kstat_seq_ops
= {
310 .show
= kstat_seq_show
,
311 .start
= kstat_seq_start
,
312 .next
= kstat_seq_next
,
313 .stop
= kstat_seq_stop
,
317 proc_kstat_open(struct inode
*inode
, struct file
*filp
)
322 rc
= seq_open(filp
, &kstat_seq_ops
);
326 f
= filp
->private_data
;
327 f
->private = PDE(inode
)->data
;
332 static struct file_operations proc_kstat_operations
= {
333 .open
= proc_kstat_open
,
336 .release
= seq_release
,
340 __kstat_create(const char *ks_module
, int ks_instance
, const char *ks_name
,
341 const char *ks_class
, uchar_t ks_type
, uint_t ks_ndata
,
347 ASSERT(ks_instance
== 0);
349 ASSERT(!(ks_flags
& KSTAT_FLAG_UNSUPPORTED
));
351 if ((ks_type
== KSTAT_TYPE_INTR
) || (ks_type
== KSTAT_TYPE_IO
))
352 ASSERT(ks_ndata
== 1);
354 ksp
= kmem_zalloc(sizeof(*ksp
), KM_SLEEP
);
358 spin_lock(&kstat_lock
);
359 ksp
->ks_kid
= kstat_id
;
361 spin_unlock(&kstat_lock
);
363 ksp
->ks_magic
= KS_MAGIC
;
364 mutex_init(&ksp
->ks_lock
, NULL
, MUTEX_DEFAULT
, NULL
);
365 INIT_LIST_HEAD(&ksp
->ks_list
);
367 ksp
->ks_crtime
= gethrtime();
368 ksp
->ks_snaptime
= ksp
->ks_crtime
;
369 strncpy(ksp
->ks_module
, ks_module
, KSTAT_STRLEN
);
370 ksp
->ks_instance
= ks_instance
;
371 strncpy(ksp
->ks_name
, ks_name
, KSTAT_STRLEN
);
372 strncpy(ksp
->ks_class
, ks_class
, KSTAT_STRLEN
);
373 ksp
->ks_type
= ks_type
;
374 ksp
->ks_flags
= ks_flags
;
375 ksp
->ks_update
= kstat_default_update
;
376 ksp
->ks_private
= NULL
;
378 switch (ksp
->ks_type
) {
381 ksp
->ks_data_size
= ks_ndata
;
383 case KSTAT_TYPE_NAMED
:
384 ksp
->ks_ndata
= ks_ndata
;
385 ksp
->ks_data_size
= ks_ndata
* sizeof(kstat_named_t
);
387 case KSTAT_TYPE_INTR
:
388 ksp
->ks_ndata
= ks_ndata
;
389 ksp
->ks_data_size
= ks_ndata
* sizeof(kstat_intr_t
);
392 ksp
->ks_ndata
= ks_ndata
;
393 ksp
->ks_data_size
= ks_ndata
* sizeof(kstat_io_t
);
395 case KSTAT_TYPE_TIMER
:
396 ksp
->ks_ndata
= ks_ndata
;
397 ksp
->ks_data_size
= ks_ndata
* sizeof(kstat_timer_t
);
400 PANIC("Undefined kstat type %d\n", ksp
->ks_type
);
403 if (ksp
->ks_flags
& KSTAT_FLAG_VIRTUAL
) {
406 ksp
->ks_data
= kmem_alloc(ksp
->ks_data_size
, KM_SLEEP
);
407 if (ksp
->ks_data
== NULL
) {
408 kmem_free(ksp
, sizeof(*ksp
));
415 EXPORT_SYMBOL(__kstat_create
);
418 __kstat_install(kstat_t
*ksp
)
420 struct proc_dir_entry
*de_module
, *de_name
;
425 spin_lock(&kstat_lock
);
427 /* Item may only be added to the list once */
428 list_for_each_entry(tmp
, &kstat_list
, ks_list
) {
430 spin_unlock(&kstat_lock
);
431 SGOTO(out
, rc
= -EEXIST
);
435 list_add_tail(&ksp
->ks_list
, &kstat_list
);
436 spin_unlock(&kstat_lock
);
438 de_module
= proc_dir_entry_find(proc_spl_kstat
, ksp
->ks_module
);
439 if (de_module
== NULL
) {
440 de_module
= proc_mkdir(ksp
->ks_module
, proc_spl_kstat
);
441 if (de_module
== NULL
)
442 SGOTO(out
, rc
= -EUNATCH
);
445 de_name
= create_proc_entry(ksp
->ks_name
, 0444, de_module
);
447 SGOTO(out
, rc
= -EUNATCH
);
449 mutex_enter(&ksp
->ks_lock
);
450 ksp
->ks_proc
= de_name
;
451 de_name
->proc_fops
= &proc_kstat_operations
;
452 de_name
->data
= (void *)ksp
;
453 mutex_exit(&ksp
->ks_lock
);
456 spin_lock(&kstat_lock
);
457 list_del_init(&ksp
->ks_list
);
458 spin_unlock(&kstat_lock
);
463 EXPORT_SYMBOL(__kstat_install
);
466 __kstat_delete(kstat_t
*ksp
)
468 struct proc_dir_entry
*de_module
;
470 spin_lock(&kstat_lock
);
471 list_del_init(&ksp
->ks_list
);
472 spin_unlock(&kstat_lock
);
475 de_module
= ksp
->ks_proc
->parent
;
476 remove_proc_entry(ksp
->ks_name
, de_module
);
478 /* Remove top level module directory if it's empty */
479 if (proc_dir_entries(de_module
) == 0)
480 remove_proc_entry(de_module
->name
, de_module
->parent
);
483 if (!(ksp
->ks_flags
& KSTAT_FLAG_VIRTUAL
))
484 kmem_free(ksp
->ks_data
, ksp
->ks_data_size
);
486 mutex_destroy(&ksp
->ks_lock
);
487 kmem_free(ksp
, sizeof(*ksp
));
491 EXPORT_SYMBOL(__kstat_delete
);
497 spin_lock_init(&kstat_lock
);
498 INIT_LIST_HEAD(&kstat_list
);
507 ASSERT(list_empty(&kstat_list
));