Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce userland CPU starvation from low-priority I/Os #27

Merged
merged 1 commit into from
Oct 31, 2024

Commits on Oct 31, 2024

  1. Reduce userland CPU starvation from low-priority I/Os

    Once we have successfully read from disk we may do
    significant CPU-work on the data obtained, depending on
    features like record sizes, checksums, encryption, or
    compression.  A successful write may cause significant
    CPU-work to be done for a subsequent zio.
    
    Because our vdev_disk layer and its use of IOKit is
    fundamentally asynchronous, on some media modern
    linearized scrubs and resilvers may "gang up" on bursts of
    interactive user I/Os.
    
    Moreover, all zfs kernel threads are higher priority than
    the vast majority of userland threads, therefore the
    latter can be starved of CPU especially for a scrubbing
    pool which has a vdev count conmparable to the CPU core
    count and where data was wrtten using expensive checksums
    like sha256.
    
    Practically all our IOKit I/Os are asynchronous, but
    significant work may be done on the taskq thread, possibly
    right to the entry into the vdev_disk_io_intr() callback
    function.  We dispatch "background" I/Os into a lower
    thread-priority and lower thread-count taskq compared to
    other types of zio.
    
    In the callback function itself, for these low-priority
    I/Os we kpreempt() before before calling
    zio_delay_interrupt().  For writes, this may impose a
    system-load-dependent delay on notifying upper layers of
    zfs that IOKit has moved the buffer towards the physical
    device, generating backpressure on subsequent writes.  For
    reads, this kpreempt() gives another thread in the system
    a chance to run before we do potentially heavy-CPU actions
    (such as checksumming or decyrption) on the data IOKit has
    obtained from the storage device.
    rottegift committed Oct 31, 2024
    Configuration menu
    Copy the full SHA
    22ca3c1 View commit details
    Browse the repository at this point in the history