protonscr

Diablo II: Resurrected – Performance degradation to 15–30 FPS After ~30–50 Minutes

protonclosed
ValveSoftware/Proton#10103 · opened 2026-08-29 by connormclaud · updated 2026-08-29 · 1 comments · github
Cconnormclaud 2026-08-29 github

Compatibility Report

  • Name of the game with compatibility issues: Diablo II: Resurrected
  • Steam AppID of the game: (Non-Steam shortcut via Battle.net)

System Information

  • GPU: AMD Radeon RX 9070 / Navi 48
  • Video driver version: Mesa RADV
  • Kernel version: 7.1.12-070112-generic (with ntsync module loaded), but reproducible with various kernels including default Ubuntu
  • Link to full system information report as Gist
  • Proton version: GE-Proton 11-3 / Proton Hotfix

I confirm:

  • [x] that I haven't found an existing compatibility report for this game.
  • [x] that I have checked whether there are updates for my system available.

Symptoms

After ~30–50 minutes of continuous runtime (reproducible during active gameplay/zoning as well as simply leaving the character idle in town), the game experiences severe performance
degradation:

  • Framerate drops from a smooth 144 FPS down to a choppy 15–30 FPS.
  • The game remains interactive and continues rendering, but becomes completely single-thread bound.
  • The Main thread runs continuously at 100% of a single core's capacity (~103% CPU in ps) in a runaway syscall loop executing ~25,000 syscalls per second.
  • The rest of the multi-core system remains ~93% idle.
  • Memory usage remains completely stable (VmRSS: ~2.17 GB, no memory leak).
  • GPU utilization drops to ~14–30% and AMDGPU downclocks SCLK because frame submission to the swapchain is starved by the Main thread's loop.

Strace Telemetry (Repeating Dispatch Loop)

Tracing the Main thread during the lag state reveals a repeating 16-syscall dispatch sequence running ~1,500 times per second:

19:22:23.597950 ioctl(15, NTSYNC_IOC_WAIT_ANY, 0x1000fec90) = 0 <0.010574>
19:22:23.608909 rt_sigprocmask(SIG_BLOCK, [HUP INT USR1 USR2 ALRM CHLD IO], [], 8) = 0 <0.000004>
19:22:23.608955 write(5, "\32\1\0\0\0\0\0\0\0\0\0\0\1\0\0\0\344\1\5\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 64) = 64 <0.000009>
19:22:23.608979 readv(11, [{iov_base="\0\0\0\0\0\0\0\0\344\1\5\0\0\0\0\0\1\0\0\0\263\2\0\0\1\0\0\0\263\2\0\0"..., iov_len=64}], 1) = 64 <0.000004>
19:22:23.608999 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 <0.000002>
19:22:23.609036 futex(0x7559ea4168ac, FUTEX_WAKE_PRIVATE, 1) = 1 <0.000003>
19:22:23.609049 futex(0x7559ea4168ac, FUTEX_WAKE_PRIVATE, 1) = 1 <0.000002>
19:22:23.609057 futex(0x7559ea4168a4, FUTEX_WAKE_PRIVATE, 1) = 1 <0.000002>
19:22:23.609065 futex(0x7559ea4168a4, FUTEX_WAKE_PRIVATE, 1) = 1 <0.000003>
19:22:23.609073 futex(0x7559ea4168b4, FUTEX_WAKE_PRIVATE, 1) = 1 <0.000003>
19:22:23.609082 futex(0x7559ea4168b4, FUTEX_WAKE_PRIVATE, 1) = 1 <0.000003>
19:22:23.609092 futex(0x7559ea4168b8, FUTEX_WAKE_PRIVATE, 1) = 1 <0.000002>
19:22:23.609099 futex(0x7559ea4168b8, FUTEX_WAKE_PRIVATE, 1) = 1 <0.000002>
19:22:23.609106 futex(0x7559ea416898, FUTEX_WAKE_PRIVATE, 1) = 1 <0.000002>
19:22:23.609113 futex(0x7559ea416898, FUTEX_WAKE_PRIVATE, 1) = 1 <0.000002>
19:22:23.609120 futex(0x7559ea4168c0, FUTEX_WAKE_PRIVATE, 1) = 1 <0.000002>
19:22:23.609126 futex(0x7559ea4168c0, FUTEX_WAKE_PRIVATE, 1) = 1 <0.000002>

GDB Call Stacks (Captured Live During Lag State)

Main Thread (Thread 1 - LWP 68122):

#0  __GI___ioctl (fd=15, request=3223867010) at ../sysdeps/unix/sysv/linux/ioctl.c:36
#1  0x00007559ebf157ba in linux_wait_objs () from .../ntdll.so
#2  0x00007559ebf16b25 in inproc_wait () from .../ntdll.so
#3  0x00007559ebf1a5bc in NtWaitForSingleObject () from .../ntdll.so
#4  0x00007559ebf081f6 in __wine_syscall_dispatcher () from .../ntdll.so
#5  0x00007559ebf06368 in server_init_process_done () from .../ntdll.so

Background Loop Thread (Thread 54 - LWP 68129):

#0  __GI___ioctl (fd=15, request=3223867010) at ../sysdeps/unix/sysv/linux/ioctl.c:36
#1  0x00007559ebf157ba in linux_wait_objs () from .../ntdll.so
#2  0x00007559ebf16a43 in inproc_wait () from .../ntdll.so
#3  0x00007559ebf1a5bc in NtWaitForSingleObject () from .../ntdll.so
#4  0x00007559ebf081f6 in __wine_syscall_dispatcher () from .../ntdll.so
#5  0x00007559ebf27c7e in start_thread () from .../ntdll.so

VKD3D Fence Thread (Thread 25 - LWP 68189):

#0  syscall () at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:38
#1  0x00007559ebf1d6c8 in NtWaitForAlertByThreadId () from .../ntdll.so
#2  0x00007559ebf081f6 in __wine_syscall_dispatcher () from .../ntdll.so
#3  0x00007559ebf27c7e in start_thread () from .../ntdll.so

Comparison: Healthy State vs. Lagging State

Telemetry Metric                                          │ Healthy State (Early Session)                            │ Lagging State (After ~30–50 min)
───────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────
Frame Sleep Behavior                                      │ Clean ~1.65 ms pselect6 frame timer sleeps               │ pselect6 frame sleeps absent; continuous 0-timeout loop
Syscall Rate                                              │ Standard frame-rate dispatch                             │ ~25,000 syscalls/sec (4,100 ioctl + 7,600 futex / 0.5s)
Main Thread CPU                                           │ Work distributed across worker threads                   │ Single-thread bound (~103% CPU in ps)
GPU Clock / Busy                                          │ 2420–2520 MHz @ ~90% load                                │ Drops to ~652–1570 MHz @ 14–30% load due to starved submission
Process Memory                                            │ VmRSS: ~2.10 GB                                          │ VmRSS: ~2.17 GB (Stable, no memory leak)

Reproduction

  1. Launch Diablo II: Resurrected via Battle.net under Proton.
  2. Enter a game and play normally (or leave the character idle in town).
  3. After ~30–50 minutes, observe that the framerate drops from 144 to 15–30 FPS and the Main thread begins running a continuous 25,000 syscalls/sec dispatch loop.
Kkisak-valve maintainer 2026-08-29 github

Hello @connormclaud, we're using one issue report per unofficially supported game title, so I've gone ahead and transferred this issue report to https://github.com/ValveSoftware/Proton/issues/10013#issuecomment-5463994570.

Proton versions

Upstream links