aboutsummaryrefslogtreecommitdiffstats
path: root/module/zfs/txg.c
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2013-10-01 09:50:50 -0700
committerBrian Behlendorf <[email protected]>2013-10-25 13:57:25 -0700
commit0b1401ee911c5a0c0bdb7a8e6ad36840cea3af24 (patch)
treede82f4e044f88d0d4d94541adf9da19859191421 /module/zfs/txg.c
parent1421c89142376bfd41e4de22ed7c7846b9e41f95 (diff)
Add visibility in to txg sync behavior
This change is an attempt to add visibility in to how txgs are being formed on a system, in real time. To do this, a list was added to the in memory SPA data structure for a pool, with each element on the list corresponding to txg. These entries are then exported through the kstat interface, which can then be interpreted in userspace. For each txg, the following information is exported: * Unique txg number (uint64_t) * The time the txd was born (hrtime_t) (*not* wall clock time; relative to the other entries on the list) * The current txg state ((O)pen/(Q)uiescing/(S)yncing/(C)ommitted) * The number of reserved bytes for the txg (uint64_t) * The number of bytes read during the txg (uint64_t) * The number of bytes written during the txg (uint64_t) * The number of read operations during the txg (uint64_t) * The number of write operations during the txg (uint64_t) * The time the txg was closed (hrtime_t) * The time the txg was quiesced (hrtime_t) * The time the txg was synced (hrtime_t) Note that while the raw kstat now stores relative hrtimes for the open, quiesce, and sync times. Those relative times are used to calculate how long each state took and these deltas and printed by output handlers. Signed-off-by: Brian Behlendorf <[email protected]>
Diffstat (limited to 'module/zfs/txg.c')
-rw-r--r--module/zfs/txg.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/module/zfs/txg.c b/module/zfs/txg.c
index 440353a50..7a3da8647 100644
--- a/module/zfs/txg.c
+++ b/module/zfs/txg.c
@@ -27,6 +27,7 @@
#include <sys/zfs_context.h>
#include <sys/txg_impl.h>
#include <sys/dmu_impl.h>
+#include <sys/spa_impl.h>
#include <sys/dmu_tx.h>
#include <sys/dsl_pool.h>
#include <sys/dsl_scan.h>
@@ -363,6 +364,9 @@ txg_quiesce(dsl_pool_t *dp, uint64_t txg)
ASSERT(txg == tx->tx_open_txg);
tx->tx_open_txg++;
+ spa_txg_history_set(dp->dp_spa, txg, TXG_STATE_OPEN, gethrtime());
+ spa_txg_history_add(dp->dp_spa, tx->tx_open_txg);
+
/*
* Now that we've incremented tx_open_txg, we can let threads
* enter the next transaction group.
@@ -380,6 +384,8 @@ txg_quiesce(dsl_pool_t *dp, uint64_t txg)
cv_wait(&tc->tc_cv[g], &tc->tc_lock);
mutex_exit(&tc->tc_lock);
}
+
+ spa_txg_history_set(dp->dp_spa, txg, TXG_STATE_QUIESCED, gethrtime());
}
static void
@@ -451,6 +457,7 @@ txg_sync_thread(dsl_pool_t *dp)
spa_t *spa = dp->dp_spa;
tx_state_t *tx = &dp->dp_tx;
callb_cpr_t cpr;
+ vdev_stat_t *vs1, *vs2;
uint64_t start, delta;
#ifdef _KERNEL
@@ -464,6 +471,9 @@ txg_sync_thread(dsl_pool_t *dp)
txg_thread_enter(tx, &cpr);
+ vs1 = kmem_alloc(sizeof(vdev_stat_t), KM_PUSHPAGE);
+ vs2 = kmem_alloc(sizeof(vdev_stat_t), KM_PUSHPAGE);
+
start = delta = 0;
for (;;) {
uint64_t timer, timeout;
@@ -499,8 +509,13 @@ txg_sync_thread(dsl_pool_t *dp)
txg_thread_wait(tx, &cpr, &tx->tx_quiesce_done_cv, 0);
}
- if (tx->tx_exiting)
+ if (tx->tx_exiting) {
+ kmem_free(vs2, sizeof(vdev_stat_t));
+ kmem_free(vs1, sizeof(vdev_stat_t));
txg_thread_exit(tx, &cpr, &tx->tx_sync_thread);
+ }
+
+ vdev_get_stats(spa->spa_root_vdev, vs1);
/*
* Consume the quiesced txg which has been handed off to
@@ -529,6 +544,16 @@ txg_sync_thread(dsl_pool_t *dp)
* Dispatch commit callbacks to worker threads.
*/
txg_dispatch_callbacks(dp, txg);
+
+ vdev_get_stats(spa->spa_root_vdev, vs2);
+ spa_txg_history_set_io(spa, txg,
+ vs2->vs_bytes[ZIO_TYPE_READ]-vs1->vs_bytes[ZIO_TYPE_READ],
+ vs2->vs_bytes[ZIO_TYPE_WRITE]-vs1->vs_bytes[ZIO_TYPE_WRITE],
+ vs2->vs_ops[ZIO_TYPE_READ]-vs1->vs_ops[ZIO_TYPE_READ],
+ vs2->vs_ops[ZIO_TYPE_WRITE]-vs1->vs_ops[ZIO_TYPE_WRITE],
+ dp->dp_space_towrite[txg & TXG_MASK] +
+ dp->dp_tempreserved[txg & TXG_MASK] / 2);
+ spa_txg_history_set(spa, txg, TXG_STATE_SYNCED, gethrtime());
}
}