* Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
* Copyright (C) 2007 The Regents of the University of California.
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
* Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
* Copyright (C) 2007 The Regents of the University of California.
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
vmem_free(ksp->ks_raw_buf, ksp->ks_raw_bufsize);
ksp->ks_raw_bufsize = MIN(ksp->ks_raw_bufsize * 2, KSTAT_RAW_MAX);
ksp->ks_raw_buf = vmem_alloc(ksp->ks_raw_bufsize, KM_SLEEP);
vmem_free(ksp->ks_raw_buf, ksp->ks_raw_bufsize);
ksp->ks_raw_bufsize = MIN(ksp->ks_raw_bufsize * 2, KSTAT_RAW_MAX);
ksp->ks_raw_buf = vmem_alloc(ksp->ks_raw_bufsize, KM_SLEEP);
+ return (0);
+}
+
+void
+kstat_waitq_enter(kstat_io_t *kiop)
+{
+ hrtime_t new, delta;
+ ulong_t wcnt;
+
+ new = gethrtime();
+ delta = new - kiop->wlastupdate;
+ kiop->wlastupdate = new;
+ wcnt = kiop->wcnt++;
+ if (wcnt != 0) {
+ kiop->wlentime += delta * wcnt;
+ kiop->wtime += delta;
+ }
+}
+EXPORT_SYMBOL(kstat_waitq_enter);
+
+void
+kstat_waitq_exit(kstat_io_t *kiop)
+{
+ hrtime_t new, delta;
+ ulong_t wcnt;
+
+ new = gethrtime();
+ delta = new - kiop->wlastupdate;
+ kiop->wlastupdate = new;
+ wcnt = kiop->wcnt--;
+ ASSERT((int)wcnt > 0);
+ kiop->wlentime += delta * wcnt;
+ kiop->wtime += delta;
+}
+EXPORT_SYMBOL(kstat_waitq_exit);
+
+void
+kstat_runq_enter(kstat_io_t *kiop)
+{
+ hrtime_t new, delta;
+ ulong_t rcnt;
+
+ new = gethrtime();
+ delta = new - kiop->rlastupdate;
+ kiop->rlastupdate = new;
+ rcnt = kiop->rcnt++;
+ if (rcnt != 0) {
+ kiop->rlentime += delta * rcnt;
+ kiop->rtime += delta;
+ }
+}
+EXPORT_SYMBOL(kstat_runq_enter);
+
+void
+kstat_runq_exit(kstat_io_t *kiop)
+{
+ hrtime_t new, delta;
+ ulong_t rcnt;
+
+ new = gethrtime();
+ delta = new - kiop->rlastupdate;
+ kiop->rlastupdate = new;
+ rcnt = kiop->rcnt--;
+ ASSERT((int)rcnt > 0);
+ kiop->rlentime += delta * rcnt;
+ kiop->rtime += delta;
- seq_printf(f, "%d %d 0x%02x %d %d %lld %lld\n",
- ksp->ks_kid, ksp->ks_type, ksp->ks_flags,
- ksp->ks_ndata, (int)ksp->ks_data_size,
- ksp->ks_crtime, ksp->ks_snaptime);
+ seq_printf(f, "%d %d 0x%02x %d %d %lld %lld\n",
+ ksp->ks_kid, ksp->ks_type, ksp->ks_flags,
+ ksp->ks_ndata, (int)ksp->ks_data_size,
+ ksp->ks_crtime, ksp->ks_snaptime);
- seq_puts(f, ksp->ks_raw_buf);
- } else {
- seq_printf(f, "raw data\n");
- }
- break;
- case KSTAT_TYPE_NAMED:
- seq_printf(f, "%-31s %-4s %s\n",
- "name", "type", "data");
- break;
- case KSTAT_TYPE_INTR:
- seq_printf(f, "%-8s %-8s %-8s %-8s %-8s\n",
- "hard", "soft", "watchdog",
- "spurious", "multsvc");
- break;
- case KSTAT_TYPE_IO:
- seq_printf(f,
- "%-8s %-8s %-8s %-8s %-8s %-8s "
- "%-8s %-8s %-8s %-8s %-8s %-8s\n",
- "nread", "nwritten", "reads", "writes",
- "wtime", "wlentime", "wupdate",
- "rtime", "rlentime", "rupdate",
- "wcnt", "rcnt");
- break;
- case KSTAT_TYPE_TIMER:
- seq_printf(f,
- "%-31s %-8s "
- "%-8s %-8s %-8s %-8s %-8s\n",
- "name", "events", "elapsed",
- "min", "max", "start", "stop");
- break;
- default:
- PANIC("Undefined kstat type %d\n", ksp->ks_type);
- }
-
- return -rc;
+ seq_puts(f, ksp->ks_raw_buf);
+ } else {
+ seq_printf(f, "raw data\n");
+ }
+ break;
+ case KSTAT_TYPE_NAMED:
+ seq_printf(f, "%-31s %-4s %s\n",
+ "name", "type", "data");
+ break;
+ case KSTAT_TYPE_INTR:
+ seq_printf(f, "%-8s %-8s %-8s %-8s %-8s\n",
+ "hard", "soft", "watchdog",
+ "spurious", "multsvc");
+ break;
+ case KSTAT_TYPE_IO:
+ seq_printf(f,
+ "%-8s %-8s %-8s %-8s %-8s %-8s "
+ "%-8s %-8s %-8s %-8s %-8s %-8s\n",
+ "nread", "nwritten", "reads", "writes",
+ "wtime", "wlentime", "wupdate",
+ "rtime", "rlentime", "rupdate",
+ "wcnt", "rcnt");
+ break;
+ case KSTAT_TYPE_TIMER:
+ seq_printf(f,
+ "%-31s %-8s "
+ "%-8s %-8s %-8s %-8s %-8s\n",
+ "name", "events", "elapsed",
+ "min", "max", "start", "stop");
+ break;
+ default:
+ PANIC("Undefined kstat type %d\n", ksp->ks_type);
+ }
+
+ return (-rc);
- seq_printf(f, "%-31s %-4d ", knp->name, knp->data_type);
-
- switch (knp->data_type) {
- case KSTAT_DATA_CHAR:
- knp->value.c[15] = '\0'; /* NULL terminate */
- seq_printf(f, "%-16s", knp->value.c);
- break;
- /* XXX - We need to be more careful able what tokens are
- * used for each arch, for now this is correct for x86_64.
- */
- case KSTAT_DATA_INT32:
- seq_printf(f, "%d", knp->value.i32);
- break;
- case KSTAT_DATA_UINT32:
- seq_printf(f, "%u", knp->value.ui32);
- break;
- case KSTAT_DATA_INT64:
- seq_printf(f, "%lld", (signed long long)knp->value.i64);
- break;
- case KSTAT_DATA_UINT64:
- seq_printf(f, "%llu", (unsigned long long)knp->value.ui64);
- break;
- case KSTAT_DATA_LONG:
- seq_printf(f, "%ld", knp->value.l);
- break;
- case KSTAT_DATA_ULONG:
- seq_printf(f, "%lu", knp->value.ul);
- break;
- case KSTAT_DATA_STRING:
- KSTAT_NAMED_STR_PTR(knp)
- [KSTAT_NAMED_STR_BUFLEN(knp)-1] = '\0';
- seq_printf(f, "%s", KSTAT_NAMED_STR_PTR(knp));
- break;
- default:
- PANIC("Undefined kstat data type %d\n", knp->data_type);
- }
-
- seq_printf(f, "\n");
-
- return 0;
+ seq_printf(f, "%-31s %-4d ", knp->name, knp->data_type);
+
+ switch (knp->data_type) {
+ case KSTAT_DATA_CHAR:
+ knp->value.c[15] = '\0'; /* NULL terminate */
+ seq_printf(f, "%-16s", knp->value.c);
+ break;
+ /*
+ * NOTE - We need to be more careful able what tokens are
+ * used for each arch, for now this is correct for x86_64.
+ */
+ case KSTAT_DATA_INT32:
+ seq_printf(f, "%d", knp->value.i32);
+ break;
+ case KSTAT_DATA_UINT32:
+ seq_printf(f, "%u", knp->value.ui32);
+ break;
+ case KSTAT_DATA_INT64:
+ seq_printf(f, "%lld", (signed long long)knp->value.i64);
+ break;
+ case KSTAT_DATA_UINT64:
+ seq_printf(f, "%llu",
+ (unsigned long long)knp->value.ui64);
+ break;
+ case KSTAT_DATA_LONG:
+ seq_printf(f, "%ld", knp->value.l);
+ break;
+ case KSTAT_DATA_ULONG:
+ seq_printf(f, "%lu", knp->value.ul);
+ break;
+ case KSTAT_DATA_STRING:
+ KSTAT_NAMED_STR_PTR(knp)
+ [KSTAT_NAMED_STR_BUFLEN(knp)-1] = '\0';
+ seq_printf(f, "%s", KSTAT_NAMED_STR_PTR(knp));
+ break;
+ default:
+ PANIC("Undefined kstat data type %d\n", knp->data_type);
+ }
+
+ seq_printf(f, "\n");
+
+ return (0);
- seq_printf(f, "%-8u %-8u %-8u %-8u %-8u\n",
- kip->intrs[KSTAT_INTR_HARD],
- kip->intrs[KSTAT_INTR_SOFT],
- kip->intrs[KSTAT_INTR_WATCHDOG],
- kip->intrs[KSTAT_INTR_SPURIOUS],
- kip->intrs[KSTAT_INTR_MULTSVC]);
-
- return 0;
+ seq_printf(f, "%-8u %-8u %-8u %-8u %-8u\n",
+ kip->intrs[KSTAT_INTR_HARD],
+ kip->intrs[KSTAT_INTR_SOFT],
+ kip->intrs[KSTAT_INTR_WATCHDOG],
+ kip->intrs[KSTAT_INTR_SPURIOUS],
+ kip->intrs[KSTAT_INTR_MULTSVC]);
+
+ return (0);
- seq_printf(f,
- "%-8llu %-8llu %-8u %-8u %-8lld %-8lld "
- "%-8lld %-8lld %-8lld %-8lld %-8u %-8u\n",
- kip->nread, kip->nwritten,
- kip->reads, kip->writes,
- kip->wtime, kip->wlentime, kip->wlastupdate,
- kip->rtime, kip->wlentime, kip->rlastupdate,
- kip->wcnt, kip->rcnt);
-
- return 0;
+ seq_printf(f,
+ "%-8llu %-8llu %-8u %-8u %-8lld %-8lld "
+ "%-8lld %-8lld %-8lld %-8lld %-8u %-8u\n",
+ kip->nread, kip->nwritten,
+ kip->reads, kip->writes,
+ kip->wtime, kip->wlentime, kip->wlastupdate,
+ kip->rtime, kip->rlentime, kip->rlastupdate,
+ kip->wcnt, kip->rcnt);
+
+ return (0);
- seq_printf(f,
- "%-31s %-8llu %-8lld %-8lld %-8lld %-8lld %-8lld\n",
- ktp->name, ktp->num_events, ktp->elapsed_time,
- ktp->min_time, ktp->max_time,
- ktp->start_time, ktp->stop_time);
+ seq_printf(f,
+ "%-31s %-8llu %-8lld %-8lld %-8lld %-8lld %-8lld\n",
+ ktp->name, ktp->num_events, ktp->elapsed_time,
+ ktp->min_time, ktp->max_time,
+ ktp->start_time, ktp->stop_time);
- seq_puts(f, ksp->ks_raw_buf);
- } else {
- ASSERT(ksp->ks_ndata == 1);
- rc = kstat_seq_show_raw(f, ksp->ks_data,
- ksp->ks_data_size);
- }
- break;
- case KSTAT_TYPE_NAMED:
- rc = kstat_seq_show_named(f, (kstat_named_t *)p);
- break;
- case KSTAT_TYPE_INTR:
- rc = kstat_seq_show_intr(f, (kstat_intr_t *)p);
- break;
- case KSTAT_TYPE_IO:
- rc = kstat_seq_show_io(f, (kstat_io_t *)p);
- break;
- case KSTAT_TYPE_TIMER:
- rc = kstat_seq_show_timer(f, (kstat_timer_t *)p);
- break;
- default:
- PANIC("Undefined kstat type %d\n", ksp->ks_type);
- }
-
- return -rc;
+ seq_puts(f, ksp->ks_raw_buf);
+ } else {
+ ASSERT(ksp->ks_ndata == 1);
+ rc = kstat_seq_show_raw(f, ksp->ks_data,
+ ksp->ks_data_size);
+ }
+ break;
+ case KSTAT_TYPE_NAMED:
+ rc = kstat_seq_show_named(f, (kstat_named_t *)p);
+ break;
+ case KSTAT_TYPE_INTR:
+ rc = kstat_seq_show_intr(f, (kstat_intr_t *)p);
+ break;
+ case KSTAT_TYPE_IO:
+ rc = kstat_seq_show_io(f, (kstat_io_t *)p);
+ break;
+ case KSTAT_TYPE_TIMER:
+ rc = kstat_seq_show_timer(f, (kstat_timer_t *)p);
+ break;
+ default:
+ PANIC("Undefined kstat type %d\n", ksp->ks_type);
+ }
+
+ return (-rc);
- case KSTAT_TYPE_RAW:
- if (ksp->ks_raw_ops.addr)
- rc = ksp->ks_raw_ops.addr(ksp, n);
- else
- rc = ksp->ks_data;
- break;
- case KSTAT_TYPE_NAMED:
- rc = ksp->ks_data + n * sizeof(kstat_named_t);
- break;
- case KSTAT_TYPE_INTR:
- rc = ksp->ks_data + n * sizeof(kstat_intr_t);
- break;
- case KSTAT_TYPE_IO:
- rc = ksp->ks_data + n * sizeof(kstat_io_t);
- break;
- case KSTAT_TYPE_TIMER:
- rc = ksp->ks_data + n * sizeof(kstat_timer_t);
- break;
- default:
- PANIC("Undefined kstat type %d\n", ksp->ks_type);
- }
-
- SRETURN(rc);
+ case KSTAT_TYPE_RAW:
+ if (ksp->ks_raw_ops.addr)
+ rc = ksp->ks_raw_ops.addr(ksp, n);
+ else
+ rc = ksp->ks_data;
+ break;
+ case KSTAT_TYPE_NAMED:
+ rc = ksp->ks_data + n * sizeof (kstat_named_t);
+ break;
+ case KSTAT_TYPE_INTR:
+ rc = ksp->ks_data + n * sizeof (kstat_intr_t);
+ break;
+ case KSTAT_TYPE_IO:
+ rc = ksp->ks_data + n * sizeof (kstat_io_t);
+ break;
+ case KSTAT_TYPE_TIMER:
+ rc = ksp->ks_data + n * sizeof (kstat_timer_t);
+ break;
+ default:
+ PANIC("Undefined kstat type %d\n", ksp->ks_type);
+ }
+
+ return (rc);
- .show = kstat_seq_show,
- .start = kstat_seq_start,
- .next = kstat_seq_next,
- .stop = kstat_seq_stop,
+ .show = kstat_seq_show,
+ .start = kstat_seq_start,
+ .next = kstat_seq_next,
+ .stop = kstat_seq_stop,
- int (*headers)(char *buf, size_t size),
- int (*data)(char *buf, size_t size, void *data),
- void *(*addr)(kstat_t *ksp, loff_t index))
+ int (*headers)(char *buf, size_t size),
+ int (*data)(char *buf, size_t size, void *data),
+ void *(*addr)(kstat_t *ksp, loff_t index))
mutex_init(&ksp->ks_private_lock, NULL, MUTEX_DEFAULT, NULL);
ksp->ks_lock = &ksp->ks_private_lock;
INIT_LIST_HEAD(&ksp->ks_list);
ksp->ks_crtime = gethrtime();
mutex_init(&ksp->ks_private_lock, NULL, MUTEX_DEFAULT, NULL);
ksp->ks_lock = &ksp->ks_private_lock;
INIT_LIST_HEAD(&ksp->ks_list);
ksp->ks_crtime = gethrtime();
strncpy(ksp->ks_module, ks_module, KSTAT_STRLEN);
ksp->ks_instance = ks_instance;
strncpy(ksp->ks_name, ks_name, KSTAT_STRLEN);
strncpy(ksp->ks_module, ks_module, KSTAT_STRLEN);
ksp->ks_instance = ks_instance;
strncpy(ksp->ks_name, ks_name, KSTAT_STRLEN);
- case KSTAT_TYPE_RAW:
- ksp->ks_ndata = 1;
- ksp->ks_data_size = ks_ndata;
- break;
- case KSTAT_TYPE_NAMED:
- ksp->ks_ndata = ks_ndata;
- ksp->ks_data_size = ks_ndata * sizeof(kstat_named_t);
- break;
- case KSTAT_TYPE_INTR:
- ksp->ks_ndata = ks_ndata;
- ksp->ks_data_size = ks_ndata * sizeof(kstat_intr_t);
- break;
- case KSTAT_TYPE_IO:
- ksp->ks_ndata = ks_ndata;
- ksp->ks_data_size = ks_ndata * sizeof(kstat_io_t);
- break;
- case KSTAT_TYPE_TIMER:
- ksp->ks_ndata = ks_ndata;
- ksp->ks_data_size = ks_ndata * sizeof(kstat_timer_t);
- break;
- default:
- PANIC("Undefined kstat type %d\n", ksp->ks_type);
- }
+ case KSTAT_TYPE_RAW:
+ ksp->ks_ndata = 1;
+ ksp->ks_data_size = ks_ndata;
+ break;
+ case KSTAT_TYPE_NAMED:
+ ksp->ks_ndata = ks_ndata;
+ ksp->ks_data_size = ks_ndata * sizeof (kstat_named_t);
+ break;
+ case KSTAT_TYPE_INTR:
+ ksp->ks_ndata = ks_ndata;
+ ksp->ks_data_size = ks_ndata * sizeof (kstat_intr_t);
+ break;
+ case KSTAT_TYPE_IO:
+ ksp->ks_ndata = ks_ndata;
+ ksp->ks_data_size = ks_ndata * sizeof (kstat_io_t);
+ break;
+ case KSTAT_TYPE_TIMER:
+ ksp->ks_ndata = ks_ndata;
+ ksp->ks_data_size = ks_ndata * sizeof (kstat_timer_t);
+ break;
+ default:
+ PANIC("Undefined kstat type %d\n", ksp->ks_type);
+ }
+static int
+kstat_detect_collision(kstat_t *ksp)
+{
+ kstat_module_t *module;
+ kstat_t *tmp;
+ char *parent;
+ char *cp;
+
+ parent = kmem_asprintf("%s", ksp->ks_module);
+
+ if ((cp = strrchr(parent, '/')) == NULL) {
+ strfree(parent);
+ return (0);
+ }
+
+ cp[0] = '\0';
+ if ((module = kstat_find_module(parent)) != NULL) {
+ list_for_each_entry(tmp, &module->ksm_kstat_list, ks_list) {
+ if (strncmp(tmp->ks_name, cp+1, KSTAT_STRLEN) == 0) {
+ strfree(parent);
+ return (EEXIST);
+ }
+ }
+ }
+
+ strfree(parent);
+ return (0);
+}
+