Illumos #1313: Integer overflow in txg_delay()
authorMartin Matuska <mm@FreeBSD.org>
Mon, 1 Aug 2011 17:34:06 +0000 (10:34 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Mon, 1 Aug 2011 19:09:43 +0000 (12:09 -0700)
commitcddafdcbc55a38cdbdd3dc8c58f447b22bd847ee
tree20c50c86e64ab200b8d3ac8035bff2a9d086489c
parent0b7936d5c2337bc976ac831c1c38de563844c36b
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 <behlendorf1@llnl.gov>
Issue #352
module/zfs/txg.c