ZIL: Improve write log size accounting

Before this change write log size TXG throttling mechanism was
accounting only user payload bytes.  But the actual ZIL both on
disk and especially in memory include headers of hundred(s) of
bytes.  Not accouting those may allow applications like
bonnie++, in their wisdom writing one byte at a time, to consume
excessive amount of memory and ZIL/SLOG in one TXG.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Rob Norris <robn@despairlabs.com>
Signed-off-by:	Alexander Motin <mav@FreeBSD.org>
Sponsored by:	iXsystems, Inc.
Closes #17373
This commit is contained in:
Alexander Motin 2025-05-23 21:48:46 -04:00 committed by GitHub
parent b01d7bd32d
commit 9d76950d67
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 12 additions and 9 deletions

View File

@ -617,8 +617,7 @@ zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
dmu_buf_impl_t *db = (dmu_buf_impl_t *)sa_get_db(zp->z_sa_hdl);
uint32_t blocksize = zp->z_blksz;
itx_wr_state_t write_state;
uint64_t gen = 0;
ssize_t size = resid;
uint64_t gen = 0, log_size = 0;
if (zil_replaying(zilog, tx) || zp->z_unlinked ||
zfs_xattr_owner_unlinked(zp)) {
@ -680,6 +679,10 @@ zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
}
}
log_size += itx->itx_size;
if (wr_state == WR_NEED_COPY)
log_size += len;
itx->itx_wr_state = wr_state;
lr->lr_foid = zp->z_id;
lr->lr_offset = off;
@ -699,9 +702,7 @@ zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
resid -= len;
}
if (write_state == WR_COPIED || write_state == WR_NEED_COPY) {
dsl_pool_wrlog_count(zilog->zl_dmu_pool, size, tx->tx_txg);
}
dsl_pool_wrlog_count(zilog->zl_dmu_pool, log_size, tx->tx_txg);
}
/*

View File

@ -871,7 +871,7 @@ zvol_log_write(zvol_state_t *zv, dmu_tx_t *tx, uint64_t offset,
uint32_t blocksize = zv->zv_volblocksize;
zilog_t *zilog = zv->zv_zilog;
itx_wr_state_t write_state;
uint64_t sz = size;
uint64_t log_size = 0;
if (zil_replaying(zilog, tx))
return;
@ -909,6 +909,10 @@ zvol_log_write(zvol_state_t *zv, dmu_tx_t *tx, uint64_t offset,
wr_state = WR_NEED_COPY;
}
log_size += itx->itx_size;
if (wr_state == WR_NEED_COPY)
log_size += len;
itx->itx_wr_state = wr_state;
lr->lr_foid = ZVOL_OBJ;
lr->lr_offset = offset;
@ -924,9 +928,7 @@ zvol_log_write(zvol_state_t *zv, dmu_tx_t *tx, uint64_t offset,
size -= len;
}
if (write_state == WR_COPIED || write_state == WR_NEED_COPY) {
dsl_pool_wrlog_count(zilog->zl_dmu_pool, sz, tx->tx_txg);
}
dsl_pool_wrlog_count(zilog->zl_dmu_pool, log_size, tx->tx_txg);
}
/*