Root Cause Diagnosis
Linux load average counts tasks in the runnable state (R) plus tasks in uninterruptible sleep (D), so processes blocked inside the kernel waiting on I/O inflate the load figure without consuming CPU cycles or memory. The blocked tasks are almost always waiting on a storage device, a network filesystem (NFS/CIFS), a hung or saturated disk queue, a failing drive, or a kernel lock, and they cannot be killed by signals until the I/O completes or times out. The fix is to identify which device, mount, or driver the D state tasks are blocked on, then resolve that dependency.
Quick Fix
List the tasks in D state and the kernel function they are blocked in:
ps -eo state,pid,ppid,user,wchan:32,cmd | awk '$1=="D"'
Count them and watch device saturation at the same time:
ps -eo state | grep -c '^D'
iostat -xz 1 5
If the wchan column shows nfs_*, rpc_*, or io_schedule, the blocker is a stalled mount or a saturated disk. For a hung NFS mount, lazily detach it:
umount -f -l /mnt/nfs_share
Step-by-Step Resolution
1. Confirm the load is I/O wait and not CPU
uptime
vmstat 1 5
In vmstat, a high b column (blocked processes) and a high wa value, with low us and sy, confirm uninterruptible sleep. Compare with r (runnable); if b is large and r is small, the load is I/O driven.
cat /proc/pressure/io
cat /proc/pressure/cpu
cat /proc/pressure/memory
On kernels 4.20 or later with PSI enabled, some avg10 in /proc/pressure/io above roughly 10 confirms I/O stall. If the file is missing, add psi=1 to the kernel command line.
2. Identify the blocked processes and their kernel stacks
# Per-process state and wait channel
ps -eo pid,stat,wchan:32,cmd | awk '$2 ~ /^D/'
# Full kernel stack of a specific blocked PID (requires root)
cat /proc/<PID>/stack
# Dump all blocked task stacks to the kernel log
echo w > /proc/sysrq-trigger
dmesg | tail -n 200
Enable SysRq first if it is disabled:
sysctl -w kernel.sysrq=1
Look for frames such as nfs_wait_bit_killable, jbd2_log_wait_commit, blk_mq_get_tag, wait_on_page_bit, or scsi_*. The top frame identifies the subsystem.
3. Map the block to a device or mount
# Which files are open by the blocked PID
ls -l /proc/<PID>/fd
# Which process holds a mount busy
fuser -vm /mnt/nfs_share
lsof +f -- /mnt/nfs_share
lsof and fuser can themselves hang on a dead NFS mount. Use a timeout:
timeout 5 stat /mnt/nfs_share || echo "mount unresponsive"
4. Check disk health and queue saturation
iostat -xz 1 10
Check these columns: %util near 100, await (or r_await/w_await) above 20 ms on SSDs or 50 ms on HDDs, and aqu-sz (average queue size) greater than the device queue depth. High await with low throughput indicates a failing or throttled device.
# SMART health
smartctl -a /dev/sda
smartctl -H /dev/nvme0n1
# Kernel I/O errors and resets
dmesg -T | grep -Ei 'i/o error|blk_update_request|task abort|reset|timeout|nvme|ata[0-9]'
A non-zero Reallocated_Sector_Ct, Current_Pending_Sector, or repeated ata link resets point to a failing drive. Replace it, since software tuning will not fix it.
5. Find the process generating the I/O
iotop -oPa
pidstat -d 1 10
Without iotop, use:
cat /proc/<PID>/io
Rising write_bytes or read_bytes identifies the source. Throttle or reschedule the offender:
ionice -c3 -p <PID> # idle I/O class
renice +10 -p <PID>
ionice classes only take effect with the bfq or cfq scheduler, not none or mq-deadline.
6. Fix NFS and network filesystem stalls
Check current mount options:
nfsstat -m
mount | grep nfs
For a hard mount on an unreliable network, tasks stay in D state indefinitely. Use options that bound the wait in /etc/fstab:
nfs-server:/export /mnt/nfs_share nfs soft,timeo=100,retrans=3,bg,nofail,_netdev,vers=4.2 0 0
timeo is in tenths of a second, so timeo=100 is 10 seconds. soft returns an I/O error to the application instead of blocking, which risks data corruption for writes. Use hard,intr (or hard alone on kernels 2.6.25 and later, where intr is ignored) for data you cannot lose, and fix the network or server instead. Confirm server-side:
rpcinfo -p nfs-server
showmount -e nfs-server
ss -tn state established '( dport = :2049 )'
For CIFS, set echo_interval=10 and soft in the mount options, and check dmesg for CIFS: server not responding.
7. Check the I/O scheduler and queue depth
cat /sys/block/sda/queue/scheduler
cat /sys/block/sda/queue/nr_requests
cat /sys/block/sda/device/queue_depth
Set a suitable scheduler persistently with a udev rule in /etc/udev/rules.d/60-ioscheduler.rules:
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="1", ATTR{queue/scheduler}="bfq"
ACTION=="add|change", KERNEL=="nvme[0-9]*", ATTR{queue/scheduler}="none"
udevadm control --reload && udevadm trigger
8. Check writeback and dirty page settings
Large dirty-page buildup followed by synchronous flushes can block writers in D state.
sysctl vm.dirty_ratio vm.dirty_background_ratio vm.dirty_bytes vm.dirty_background_bytes
grep -E 'Dirty|Writeback' /proc/meminfo
On systems with large RAM and slow disks, use byte limits in /etc/sysctl.d/99-writeback.conf:
vm.dirty_background_bytes = 268435456
vm.dirty_bytes = 1073741824
sysctl --system
Setting the _bytes variants zeroes the matching _ratio setting.
9. Check filesystem, journal, and RAID/LVM layers
# ext4 journal commit stalls
dmesg -T | grep -Ei 'jbd2|ext4|xfs|btrfs'
# Software RAID resync consuming bandwidth
cat /proc/mdstat
# LVM snapshots slowing writes
lvs -a -o +devices
During an md resync, cap the speed in /etc/sysctl.d/99-md.conf:
dev.raid.speed_limit_max = 50000
dev.raid.speed_limit_min = 1000
Large LVM snapshots degrade write performance because of copy-on-write, so remove stale snapshots with lvremove.
10. Configure a hung task watchdog for visibility
sysctl kernel.hung_task_timeout_secs
sysctl -w kernel.hung_task_timeout_secs=60
Tasks in D state beyond this period are logged to dmesg with a stack trace. Set kernel.hung_task_panic=0 (default) unless you want a deliberate crash for a vmcore.
Why This Fails for Some Users
- Load average on Linux includes
Dstate by design: Unlike BSD and most other Unix systems, Linux counts uninterruptible tasks, so a high number is not necessarily a fault. A fixed set of long-livedDtasks (for example annfsdthread or a kernel worker) can add 1 to the load permanently. Verify that the processes inDstate are new or growing in number before treating the load as a problem. - Kernel threads in
Dstate are normal: Idle kernel threads such askworker,jbd2/*, ornfsdsometimes showDtransiently. Use PSI (/proc/pressure/io) as the authoritative metric, because it measures actual stall time. - Containers hide the cause: Inside a container,
psshows only that namespace’s processes, andiostatreports the host devices through cgroup-agnostic counters. Run diagnostics on the host, and check cgroup I/O pressure at/sys/fs/cgroup/<group>/io.pressure(cgroup v2). - Cloud and virtual disks are throttled invisibly: AWS EBS gp2 burst credits, gp3 provisioned IOPS/throughput, Azure managed disk caps, and GCP persistent disk quotas throttle I/O at the hypervisor without any error in
dmesg. The symptom is highawaitwith a constant IOPS or throughput ceiling iniostat. Check the provider’s volume metrics (BurstBalance,VolumeQueueLength) and raise the provisioned limits. - Steal time and noisy neighbors: On shared VMs,
%stinvmstatortopinflates stalls and can mimic I/O wait. Move to a dedicated instance if steal is consistently above 5%. - Swap activity with low reported RAM use: Check
vmstatcolumnssiandso. Heavy swapping on a slow device producesDtasks even whenfreeappears healthy, which happens when cgroup memory limits (not host RAM) trigger reclaim. Inspectmemory.eventsandmemory.pressurein the cgroup. softNFS mounts can corrupt data: Thesoftoption makes tasks fail rather than hang, but writes may be silently lost on timeout. Use it only for read-mostly or disposable data, and prefer fixing network or server availability.- Hung
Dprocesses cannot be killed:kill -9has no effect until the blocking call returns. If the I/O never completes (dead NFS server, failed disk, hung HBA), the only options are restoring the backend, forcing the mount off withumount -f -l, resetting the device through/sys/block/sdX/device/deleteorecho 1 > /sys/block/sdX/device/rescan, or rebooting. - Old kernels and drivers: RHEL/CentOS 6 and 7 (kernels 2.6.32 and 3.10), and drivers with known blk-mq or NVMe timeout bugs, can leave requests stuck indefinitely. Update the kernel and storage firmware, and check
nvme_core.default_ps_max_latency_us=0andpcie_aspm=offon the kernel command line for NVMe drives that drop off the bus. - Multipath failover delays: With
multipath-tools, queued I/O during path failure (queue_if_no_pathorno_path_retry queue) holds tasks inDstate indefinitely. Setno_path_retry 5(or a finite count) in /etc/multipath.conf so failures surface instead of hanging. - FUSE and userspace filesystems: A stuck FUSE daemon (sshfs, s3fs, rclone mount) puts every accessing process in
Dstate. Check/sys/fs/fuse/connections/*/and abort a hung connection withecho 1 > /sys/fs/fuse/connections/<N>/abort.