Skip to content

Commit 11647c6

Browse files
oshogbotonyhutter
authored andcommitted
Flush RRD only when TXGs contain data
This change modifies the behavior of spa_sync_time_logger when flushing the RRD database. Previously, once the sync interval elapsed, a flush would always be generated. On solid-state devices, especially when the pool was otherwise idle, this caused disks to wake up solely to write RRD data. Since RRD is best-effort telemetry, this behavior is unnecessary and wasteful. With this change, spa_sync_time_logger delays flushing until a TXG that already contains data is being synced. The RRD update is appended to that TXG instead of forcing the creation of a new write-only TXG. During pool export, flushing is forced regardless of whether the TXG contains user data. At that stage, data durability takes precedence and a write must be issued. Sponsored by: [Wasabi Technology, Inc.; Klara, Inc.] Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Mariusz Zaborski <mariusz.zaborski@klarasystems.com> Closes openzfs#18082 Closes openzfs#18138
1 parent a0350f6 commit 11647c6

File tree

1 file changed

+20
-12
lines changed

1 file changed

+20
-12
lines changed

module/zfs/spa.c

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2142,20 +2142,21 @@ spa_destroy_aux_threads(spa_t *spa)
21422142
}
21432143

21442144
static void
2145-
spa_sync_time_logger(spa_t *spa, uint64_t txg)
2145+
spa_sync_time_logger(spa_t *spa, uint64_t txg, boolean_t force)
21462146
{
2147-
uint64_t curtime;
2147+
uint64_t curtime, dirty;
21482148
dmu_tx_t *tx;
2149+
dsl_pool_t *dp = spa->spa_dsl_pool;
2150+
uint64_t idx = txg & TXG_MASK;
21492151

21502152
if (!spa_writeable(spa)) {
21512153
return;
21522154
}
2153-
curtime = gethrestime_sec();
2154-
if (curtime < spa->spa_last_noted_txg_time + spa_note_txg_time) {
2155-
return;
2156-
}
21572155

2158-
if (txg > spa->spa_last_noted_txg) {
2156+
curtime = gethrestime_sec();
2157+
if (txg > spa->spa_last_noted_txg &&
2158+
(force ||
2159+
curtime >= spa->spa_last_noted_txg_time + spa_note_txg_time)) {
21592160
spa->spa_last_noted_txg_time = curtime;
21602161
spa->spa_last_noted_txg = txg;
21612162

@@ -2164,14 +2165,23 @@ spa_sync_time_logger(spa_t *spa, uint64_t txg)
21642165
mutex_exit(&spa->spa_txg_log_time_lock);
21652166
}
21662167

2167-
if (curtime < spa->spa_last_flush_txg_time + spa_flush_txg_time) {
2168+
if (!force &&
2169+
curtime < spa->spa_last_flush_txg_time + spa_flush_txg_time) {
21682170
return;
21692171
}
21702172
if (txg > spa_final_dirty_txg(spa)) {
21712173
return;
21722174
}
21732175
spa->spa_last_flush_txg_time = curtime;
21742176

2177+
mutex_enter(&dp->dp_lock);
2178+
dirty = dp->dp_dirty_pertxg[idx];
2179+
mutex_exit(&dp->dp_lock);
2180+
if (!force && dirty == 0) {
2181+
return;
2182+
}
2183+
2184+
spa->spa_last_flush_txg_time = curtime;
21752185
tx = dmu_tx_create_assigned(spa_get_dsl(spa), txg);
21762186

21772187
VERIFY0(zap_update(spa_meta_objset(spa), DMU_POOL_DIRECTORY_OBJECT,
@@ -2194,9 +2204,7 @@ spa_unload_sync_time_logger(spa_t *spa)
21942204
VERIFY0(dmu_tx_assign(tx, DMU_TX_WAIT));
21952205

21962206
txg = dmu_tx_get_txg(tx);
2197-
spa->spa_last_noted_txg_time = 0;
2198-
spa->spa_last_flush_txg_time = 0;
2199-
spa_sync_time_logger(spa, txg);
2207+
spa_sync_time_logger(spa, txg, B_TRUE);
22002208

22012209
dmu_tx_commit(tx);
22022210
}
@@ -10809,7 +10817,7 @@ spa_sync(spa_t *spa, uint64_t txg)
1080910817
*/
1081010818
brt_pending_apply(spa, txg);
1081110819

10812-
spa_sync_time_logger(spa, txg);
10820+
spa_sync_time_logger(spa, txg, B_FALSE);
1081310821

1081410822
/*
1081510823
* Lock out configuration changes.

0 commit comments

Comments
 (0)