Skip to content

Commit 330847f

Browse files
ahrensbehlendorf
authored andcommitted
Illumos #3537
3537 want pool io kstats Reviewed by: George Wilson <george.wilson@delphix.com> Reviewed by: Adam Leventhal <ahl@delphix.com> Reviewed by: Eric Schrock <eric.schrock@delphix.com> Reviewed by: Sa?o Kiselkov <skiselkov.ml@gmail.com> Reviewed by: Garrett D'Amore <garrett@damore.org> Reviewed by: Brendan Gregg <brendan.gregg@joyent.com> Approved by: Gordon Ross <gwr@nexenta.com> References: http://www.illumos.org/issues/3537 illumos/illumos-gate@c3a6601 Ported by: Cyril Plisko <cyril.plisko@mountall.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Porting Notes: 1. The patch was restructured to take advantage of the existing spa statistics infrastructure. To accomplish this the kstat was moved in to spa->io_stats and the init/destroy code moved to spa_stats.c. 2. The I/O kstat was simply named <pool> which conflicted with the pool directory we had already created. Therefore it was renamed to <pool>/io 3. An update handler was added to allow the kstat to be zeroed.
1 parent a117a6d commit 330847f

File tree

5 files changed

+152
-7
lines changed

5 files changed

+152
-7
lines changed

include/sys/spa.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,7 @@ typedef struct spa_stats {
550550
spa_stats_history_t read_history;
551551
spa_stats_history_t txg_history;
552552
spa_stats_history_t tx_assign_histogram;
553+
spa_stats_history_t io_history;
553554
} spa_stats_t;
554555

555556
typedef enum txg_state {

include/sys/zfs_context.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,10 +344,16 @@ extern void cv_broadcast(kcondvar_t *cv);
344344
/*
345345
* kstat creation, installation and deletion
346346
*/
347-
extern kstat_t *kstat_create(char *, int,
348-
char *, char *, uchar_t, ulong_t, uchar_t);
347+
extern kstat_t *kstat_create(const char *, int,
348+
const char *, const char *, uchar_t, ulong_t, uchar_t);
349349
extern void kstat_install(kstat_t *);
350350
extern void kstat_delete(kstat_t *);
351+
extern void kstat_waitq_enter(kstat_io_t *);
352+
extern void kstat_waitq_exit(kstat_io_t *);
353+
extern void kstat_runq_enter(kstat_io_t *);
354+
extern void kstat_runq_exit(kstat_io_t *);
355+
extern void kstat_waitq_to_runq(kstat_io_t *);
356+
extern void kstat_runq_back_to_waitq(kstat_io_t *);
351357
extern void kstat_set_raw_ops(kstat_t *ksp,
352358
int (*headers)(char *buf, size_t size),
353359
int (*data)(char *buf, size_t size, void *data),

lib/libzpool/kernel.c

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,8 @@ zk_thread_join(kt_did_t tid)
224224
*/
225225
/*ARGSUSED*/
226226
kstat_t *
227-
kstat_create(char *module, int instance, char *name, char *class,
228-
uchar_t type, ulong_t ndata, uchar_t ks_flag)
227+
kstat_create(const char *module, int instance, const char *name,
228+
const char *class, uchar_t type, ulong_t ndata, uchar_t ks_flag)
229229
{
230230
return (NULL);
231231
}
@@ -241,6 +241,35 @@ kstat_delete(kstat_t *ksp)
241241
{}
242242

243243
/*ARGSUSED*/
244+
void
245+
kstat_waitq_enter(kstat_io_t *kiop)
246+
{}
247+
248+
/*ARGSUSED*/
249+
void
250+
kstat_waitq_exit(kstat_io_t *kiop)
251+
{}
252+
253+
/*ARGSUSED*/
254+
void
255+
kstat_runq_enter(kstat_io_t *kiop)
256+
{}
257+
258+
/*ARGSUSED*/
259+
void
260+
kstat_runq_exit(kstat_io_t *kiop)
261+
{}
262+
263+
/*ARGSUSED*/
264+
void
265+
kstat_waitq_to_runq(kstat_io_t *kiop)
266+
{}
267+
268+
/*ARGSUSED*/
269+
void
270+
kstat_runq_back_to_waitq(kstat_io_t *kiop)
271+
{}
272+
244273
void
245274
kstat_set_raw_ops(kstat_t *ksp,
246275
int (*headers)(char *buf, size_t size),

module/zfs/spa_stats.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,12 +608,61 @@ spa_tx_assign_add_nsecs(spa_t *spa, uint64_t nsecs)
608608
atomic_inc_64(&((kstat_named_t *)ssh->private)[idx].value.ui64);
609609
}
610610

611+
/*
612+
* ==========================================================================
613+
* SPA IO History Routines
614+
* ==========================================================================
615+
*/
616+
static int
617+
spa_io_history_update(kstat_t *ksp, int rw)
618+
{
619+
if (rw == KSTAT_WRITE)
620+
memset(ksp->ks_data, 0, ksp->ks_data_size);
621+
622+
return (0);
623+
}
624+
625+
static void
626+
spa_io_history_init(spa_t *spa)
627+
{
628+
spa_stats_history_t *ssh = &spa->spa_stats.io_history;
629+
char name[KSTAT_STRLEN];
630+
kstat_t *ksp;
631+
632+
mutex_init(&ssh->lock, NULL, MUTEX_DEFAULT, NULL);
633+
634+
(void) snprintf(name, KSTAT_STRLEN, "zfs/%s", spa_name(spa));
635+
name[KSTAT_STRLEN-1] = '\0';
636+
637+
ksp = kstat_create(name, 0, "io", "disk", KSTAT_TYPE_IO, 1, 0);
638+
ssh->kstat = ksp;
639+
640+
if (ksp) {
641+
ksp->ks_lock = &ssh->lock;
642+
ksp->ks_private = spa;
643+
ksp->ks_update = spa_io_history_update;
644+
kstat_install(ksp);
645+
}
646+
}
647+
648+
static void
649+
spa_io_history_destroy(spa_t *spa)
650+
{
651+
spa_stats_history_t *ssh = &spa->spa_stats.io_history;
652+
653+
if (ssh->kstat)
654+
kstat_delete(ssh->kstat);
655+
656+
mutex_destroy(&ssh->lock);
657+
}
658+
611659
void
612660
spa_stats_init(spa_t *spa)
613661
{
614662
spa_read_history_init(spa);
615663
spa_txg_history_init(spa);
616664
spa_tx_assign_init(spa);
665+
spa_io_history_init(spa);
617666
}
618667

619668
void
@@ -622,6 +671,7 @@ spa_stats_destroy(spa_t *spa)
622671
spa_tx_assign_destroy(spa);
623672
spa_txg_history_destroy(spa);
624673
spa_read_history_destroy(spa);
674+
spa_io_history_destroy(spa);
625675
}
626676

627677
#if defined(_KERNEL) && defined(HAVE_SPL)

module/zfs/vdev_queue.c

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@
2929

3030
#include <sys/zfs_context.h>
3131
#include <sys/vdev_impl.h>
32+
#include <sys/spa_impl.h>
3233
#include <sys/zio.h>
3334
#include <sys/avl.h>
35+
#include <sys/kstat.h>
3436

3537
/*
3638
* These tunables are for performance analysis.
@@ -164,15 +166,72 @@ vdev_queue_fini(vdev_t *vd)
164166
static void
165167
vdev_queue_io_add(vdev_queue_t *vq, zio_t *zio)
166168
{
169+
spa_t *spa = zio->io_spa;
170+
spa_stats_history_t *ssh = &spa->spa_stats.io_history;
171+
167172
avl_add(&vq->vq_deadline_tree, zio);
168173
avl_add(zio->io_vdev_tree, zio);
174+
175+
if (ssh->kstat != NULL) {
176+
mutex_enter(&ssh->lock);
177+
kstat_waitq_enter(ssh->kstat->ks_data);
178+
mutex_exit(&ssh->lock);
179+
}
169180
}
170181

171182
static void
172183
vdev_queue_io_remove(vdev_queue_t *vq, zio_t *zio)
173184
{
185+
spa_t *spa = zio->io_spa;
186+
spa_stats_history_t *ssh = &spa->spa_stats.io_history;
187+
174188
avl_remove(&vq->vq_deadline_tree, zio);
175189
avl_remove(zio->io_vdev_tree, zio);
190+
191+
if (ssh->kstat != NULL) {
192+
mutex_enter(&ssh->lock);
193+
kstat_waitq_exit(ssh->kstat->ks_data);
194+
mutex_exit(&ssh->lock);
195+
}
196+
}
197+
198+
static void
199+
vdev_queue_pending_add(vdev_queue_t *vq, zio_t *zio)
200+
{
201+
spa_t *spa = zio->io_spa;
202+
spa_stats_history_t *ssh = &spa->spa_stats.io_history;
203+
204+
avl_add(&vq->vq_pending_tree, zio);
205+
206+
if (ssh->kstat != NULL) {
207+
mutex_enter(&ssh->lock);
208+
kstat_runq_enter(ssh->kstat->ks_data);
209+
mutex_exit(&ssh->lock);
210+
}
211+
}
212+
213+
static void
214+
vdev_queue_pending_remove(vdev_queue_t *vq, zio_t *zio)
215+
{
216+
spa_t *spa = zio->io_spa;
217+
spa_stats_history_t *ssh = &spa->spa_stats.io_history;
218+
219+
avl_remove(&vq->vq_pending_tree, zio);
220+
221+
if (ssh->kstat != NULL) {
222+
kstat_io_t *ksio = ssh->kstat->ks_data;
223+
224+
mutex_enter(&ssh->lock);
225+
kstat_runq_exit(ksio);
226+
if (zio->io_type == ZIO_TYPE_READ) {
227+
ksio->reads++;
228+
ksio->nread += zio->io_size;
229+
} else if (zio->io_type == ZIO_TYPE_WRITE) {
230+
ksio->writes++;
231+
ksio->nwritten += zio->io_size;
232+
}
233+
mutex_exit(&ssh->lock);
234+
}
176235
}
177236

178237
static void
@@ -351,7 +410,7 @@ vdev_queue_io_to_issue(vdev_queue_t *vq, uint64_t pending_limit)
351410
zio_execute(dio);
352411
} while (dio != lio);
353412

354-
avl_add(&vq->vq_pending_tree, aio);
413+
vdev_queue_pending_add(vq, aio);
355414
list_remove(&vq->vq_io_list, vi);
356415

357416
return (aio);
@@ -374,7 +433,7 @@ vdev_queue_io_to_issue(vdev_queue_t *vq, uint64_t pending_limit)
374433
goto again;
375434
}
376435

377-
avl_add(&vq->vq_pending_tree, fio);
436+
vdev_queue_pending_add(vq, fio);
378437

379438
return (fio);
380439
}
@@ -431,7 +490,7 @@ vdev_queue_io_done(zio_t *zio)
431490

432491
mutex_enter(&vq->vq_lock);
433492

434-
avl_remove(&vq->vq_pending_tree, zio);
493+
vdev_queue_pending_remove(vq, zio);
435494

436495
zio->io_delta = gethrtime() - zio->io_timestamp;
437496
vq->vq_io_complete_ts = gethrtime();

0 commit comments

Comments
 (0)