Call gethrtime() only once per new txg creation

When transitioning current open TXG into QUIESCE state and opening
a new one txg_quiesce() calls gethrtime():
  - to mark the birth time of the new TXG
  - to record the SPA txg history kstat
  - implicitely inside spa_txg_history_add()

These timestamps are practically the same, so that the first one
can be used instead of the other two.  The only visible difference
is that inside spa_txg_history_add() the time spent in kmem_zalloc()
will be counted towards the opened TXG.

Since at this point the new TXG already exists (tx->tx_open_txg
has been already incremented) it is actually a correct accounting.

In any case this extra work is only happening when spa_txg_history
kstat is activated (i.e. zfs_txg_history > 0) and doesn't affect
the normal processing in any way.

Signed-off-by: Cyril Plisko <cyril.plisko@mountall.com>
Issue #2075
This commit is contained in:
Cyril Plisko 2014-01-15 11:26:12 +02:00 committed by Brian Behlendorf
parent 478d64fdae
commit 01b738f457
3 changed files with 5 additions and 5 deletions

View File

@ -566,7 +566,7 @@ extern void spa_stats_init(spa_t *spa);
extern void spa_stats_destroy(spa_t *spa); extern void spa_stats_destroy(spa_t *spa);
extern void spa_read_history_add(spa_t *spa, const zbookmark_t *zb, extern void spa_read_history_add(spa_t *spa, const zbookmark_t *zb,
uint32_t aflags); uint32_t aflags);
extern void spa_txg_history_add(spa_t *spa, uint64_t txg); extern void spa_txg_history_add(spa_t *spa, uint64_t txg, hrtime_t birth_time);
extern int spa_txg_history_set(spa_t *spa, uint64_t txg, extern int spa_txg_history_set(spa_t *spa, uint64_t txg,
txg_state_t completed_state, hrtime_t completed_time); txg_state_t completed_state, hrtime_t completed_time);
extern int spa_txg_history_set_io(spa_t *spa, uint64_t txg, uint64_t nread, extern int spa_txg_history_set_io(spa_t *spa, uint64_t txg, uint64_t nread,

View File

@ -422,7 +422,7 @@ spa_txg_history_destroy(spa_t *spa)
* Add a new txg to historical record. * Add a new txg to historical record.
*/ */
void void
spa_txg_history_add(spa_t *spa, uint64_t txg) spa_txg_history_add(spa_t *spa, uint64_t txg, hrtime_t birth_time)
{ {
spa_stats_history_t *ssh = &spa->spa_stats.txg_history; spa_stats_history_t *ssh = &spa->spa_stats.txg_history;
spa_txg_history_t *sth, *rm; spa_txg_history_t *sth, *rm;
@ -433,7 +433,7 @@ spa_txg_history_add(spa_t *spa, uint64_t txg)
sth = kmem_zalloc(sizeof (spa_txg_history_t), KM_PUSHPAGE); sth = kmem_zalloc(sizeof (spa_txg_history_t), KM_PUSHPAGE);
sth->txg = txg; sth->txg = txg;
sth->state = TXG_STATE_OPEN; sth->state = TXG_STATE_OPEN;
sth->times[TXG_STATE_BIRTH] = gethrtime(); sth->times[TXG_STATE_BIRTH] = birth_time;
mutex_enter(&ssh->lock); mutex_enter(&ssh->lock);

View File

@ -377,8 +377,8 @@ txg_quiesce(dsl_pool_t *dp, uint64_t txg)
tx->tx_open_txg++; tx->tx_open_txg++;
tx->tx_open_time = gethrtime(); tx->tx_open_time = gethrtime();
spa_txg_history_set(dp->dp_spa, txg, TXG_STATE_OPEN, gethrtime()); spa_txg_history_set(dp->dp_spa, txg, TXG_STATE_OPEN, tx->tx_open_time);
spa_txg_history_add(dp->dp_spa, tx->tx_open_txg); spa_txg_history_add(dp->dp_spa, tx->tx_open_txg, tx->tx_open_time);
DTRACE_PROBE2(txg__quiescing, dsl_pool_t *, dp, uint64_t, txg); DTRACE_PROBE2(txg__quiescing, dsl_pool_t *, dp, uint64_t, txg);
DTRACE_PROBE2(txg__opened, dsl_pool_t *, dp, uint64_t, tx->tx_open_txg); DTRACE_PROBE2(txg__opened, dsl_pool_t *, dp, uint64_t, tx->tx_open_txg);