From f483a97a417ca7292d6a7d516a72558d385f2370 Mon Sep 17 00:00:00 2001 From: Ned Bass Date: Mon, 26 Aug 2013 16:42:11 -0700 Subject: [PATCH] 3537 add kstat_waitq_enter and friends These kstat interfaces are required to port "Illumos #3537 want pool io kstats" to ZFS on Linux. kstat_waitq_enter() kstat_waitq_exit() kstat_runq_enter() kstat_runq_exit() Additionally, zero out the ks_data buffer in __kstat_create() so that the kstat_io_t counters are initialized to zero. Signed-off-by: Brian Behlendorf --- include/sys/kstat.h | 4 +++ module/spl/spl-kstat.c | 68 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/include/sys/kstat.h b/include/sys/kstat.h index 97d8596f7d..faf6b81dab 100644 --- a/include/sys/kstat.h +++ b/include/sys/kstat.h @@ -189,6 +189,10 @@ extern kstat_t *__kstat_create(const char *ks_module, int ks_instance, uchar_t ks_flags); extern void __kstat_install(kstat_t *ksp); extern void __kstat_delete(kstat_t *ksp); +extern void kstat_waitq_enter(kstat_io_t *); +extern void kstat_waitq_exit(kstat_io_t *); +extern void kstat_runq_enter(kstat_io_t *); +extern void kstat_runq_exit(kstat_io_t *); #define kstat_set_raw_ops(k,h,d,a) __kstat_set_raw_ops(k,h,d,a) #define kstat_create(m,i,n,c,t,s,f) __kstat_create(m,i,n,c,t,s,f) diff --git a/module/spl/spl-kstat.c b/module/spl/spl-kstat.c index 7932678d76..c604a32f2a 100644 --- a/module/spl/spl-kstat.c +++ b/module/spl/spl-kstat.c @@ -54,6 +54,72 @@ kstat_resize_raw(kstat_t *ksp) 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; +} +EXPORT_SYMBOL(kstat_runq_exit); + static int kstat_seq_show_headers(struct seq_file *f) { @@ -539,7 +605,7 @@ __kstat_create(const char *ks_module, int ks_instance, const char *ks_name, if (ksp->ks_flags & KSTAT_FLAG_VIRTUAL) { ksp->ks_data = NULL; } else { - ksp->ks_data = kmem_alloc(ksp->ks_data_size, KM_SLEEP); + ksp->ks_data = kmem_zalloc(ksp->ks_data_size, KM_SLEEP); if (ksp->ks_data == NULL) { kmem_free(ksp, sizeof(*ksp)); ksp = NULL;