diff options
author | Martin Matuska <[email protected]> | 2011-08-01 10:34:06 -0700 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2011-08-01 12:09:43 -0700 |
commit | cddafdcbc55a38cdbdd3dc8c58f447b22bd847ee (patch) | |
tree | 20c50c86e64ab200b8d3ac8035bff2a9d086489c | |
parent | 0b7936d5c2337bc976ac831c1c38de563844c36b (diff) |
Illumos #1313: Integer overflow in txg_delay()
The function txg_delay() is used to delay txg (transaction group)
threads in ZFS. The timeout value for this function is calculated
using:
int timeout = ddi_get_lbolt() + ticks;
Later, the actual wait is performed:
while (ddi_get_lbolt() < timeout &&
tx->tx_syncing_txg < txg-1 && !txg_stalled(dp))
(void) cv_timedwait(&tx->tx_quiesce_more_cv, &tx->tx_sync_lock,
timeout - ddi_get_lbolt());
The ddi_get_lbolt() function returns current uptime in clock ticks
and is typed as clock_t. The clock_t type on 64-bit architectures
is int64_t.
The "timeout" variable will overflow depending on the tick frequency
(e.g. for 1000 it will overflow in 28.855 days). This will make the
expression "ddi_get_lbolt() < timeout" always false - txg threads will
not be delayed anymore at all. This leads to a slowdown in ZFS writes.
The attached patch initializes timeout as clock_t to match the return
value of ddi_get_lbolt().
Signed-off-by: Brian Behlendorf <[email protected]>
Issue #352
-rw-r--r-- | module/zfs/txg.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/module/zfs/txg.c b/module/zfs/txg.c index 340c42ae8..d0d2b1716 100644 --- a/module/zfs/txg.c +++ b/module/zfs/txg.c @@ -506,7 +506,7 @@ void txg_delay(dsl_pool_t *dp, uint64_t txg, int ticks) { tx_state_t *tx = &dp->dp_tx; - int timeout = ddi_get_lbolt() + ticks; + clock_t timeout = ddi_get_lbolt() + ticks; /* don't delay if this txg could transition to quiesing immediately */ if (tx->tx_open_txg > txg || |