-
Notifications
You must be signed in to change notification settings - Fork 837
Description
🐛 Describe the bug
XNNPACK Disabled Workspace Mode Still Locks in execute()
NOTE: Patch was generated by Codex 5.3
Summary
With XNNPACK enabled and shared workspace disabled, ExecuTorch still acquires
XNNWorkspace's mutex in execute(). For real-time audio callbacks this adds a
blocking lock in the hot path, even though WorkspaceSharingMode::Disabled
creates one workspace per delegate instance.
Build Options This Patch Improves/Fixes
The bug is relevant to builds configured with:
-DEXECUTORCH_BUILD_XNNPACK=ON-DEXECUTORCH_XNNPACK_SHARED_WORKSPACE=OFF
What it fixes:
- Aligns behavior with
EXECUTORCH_XNNPACK_SHARED_WORKSPACE=OFFby removing
unnecessary execute-time mutex locking inWorkspaceSharingMode::Disabled.
What it preserves:
WorkspaceSharingMode::PerModelandWorkspaceSharingMode::Globalkeep
mutex locking behavior unchanged.
Problem Detail
Current flow:
XNNWorkspaceManager::get_or_create_workspace()inDisabledmode creates a
freshXNNWorkspace.XnnpackBackend::execute()always callsworkspace->acquire().XNNWorkspace::acquire()always locks the mutex.
So even in non-shared mode, each execute() call still takes a mutex lock.
ExecuTorch-Only Regression Test (Fails Without Fix)
Add this test to backends/xnnpack/test/runtime/test_workspace_manager.cpp:
TEST_F(XNNWorkspaceManagerTest, DisabledModeAcquireDoesNotLock) {
workspace_manager_->set_sharing_mode(WorkspaceSharingMode::Disabled);
auto workspace_result = workspace_manager_->get_or_create_workspace(12345);
ASSERT_TRUE(workspace_result.ok());
auto workspace = workspace_result.get();
auto [lock, ptr] = workspace->acquire();
ASSERT_NE(ptr, nullptr);
EXPECT_FALSE(lock.owns_lock());
}
TEST_F(XNNWorkspaceManagerTest, PerModelAcquireStillLocks) {
workspace_manager_->set_sharing_mode(WorkspaceSharingMode::PerModel);
auto workspace_result = workspace_manager_->get_or_create_workspace(12345);
ASSERT_TRUE(workspace_result.ok());
auto workspace = workspace_result.get();
auto [lock, ptr] = workspace->acquire();
ASSERT_NE(ptr, nullptr);
EXPECT_TRUE(lock.owns_lock());
}Without the fix, DisabledModeAcquireDoesNotLock fails because owns_lock() is
true.
Proposed Minimal Fix
Patch files:
backends/xnnpack/runtime/XNNWorkspace.hbackends/xnnpack/runtime/XNNWorkspaceManager.cpp
Patch behavior:
- Add a per-workspace
lock_required_flag (defaulttrue). - In
acquire(), return an unlockedstd::unique_lockwhen
lock_required_ == false. - In
WorkspaceSharingMode::Disabled, calldisable_locking()on the newly
created workspace.
This keeps the fix local and avoids changing behavior for shared-workspace
modes.
executorch_xnnpack_rt_lock_elision.patch
Versions
Collecting environment information...
PyTorch version: 2.10.0+cu128
Is debug build: False
CUDA used to build PyTorch: 12.8
ROCM used to build PyTorch: N/A
OS: Ubuntu 24.04.3 LTS (x86_64)
GCC version: (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0
Clang version: Could not collect
CMake version: version 3.30.9
Libc version: glibc-2.39
Python version: 3.13.3 (main, Apr 9 2025, 04:03:52) [Clang 20.1.0 ] (64-bit runtime)
Python platform: Linux-6.14.0-123037-tuxedo-x86_64-with-glibc2.39
Is CUDA available: False
CUDA runtime version: No CUDA
CUDA_MODULE_LOADING set to: N/A
GPU models and configuration: No CUDA
Nvidia driver version: No CUDA
cuDNN version: No CUDA
Is XPU available: False
HIP runtime version: N/A
MIOpen runtime version: N/A
Is XNNPACK available: True
Caching allocator config: N/A
CPU:
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Address sizes: 48 bits physical, 48 bits virtual
Byte Order: Little Endian
CPU(s): 16
On-line CPU(s) list: 0-15
Vendor ID: AuthenticAMD
Model name: AMD Ryzen 7 8845HS w/ Radeon 780M Graphics
CPU family: 25
Model: 117
Thread(s) per core: 2
Core(s) per socket: 8
Socket(s): 1
Stepping: 2
Frequency boost: enabled
CPU(s) scaling MHz: 33%
CPU max MHz: 5137.0000
CPU min MHz: 400.0000
BogoMIPS: 7585.73
Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl xtopology nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d
Virtualization: AMD-V
L1d cache: 256 KiB (8 instances)
L1i cache: 256 KiB (8 instances)
L2 cache: 8 MiB (8 instances)
L3 cache: 16 MiB (1 instance)
NUMA node(s): 1
NUMA node0 CPU(s): 0-15
Vulnerability Gather data sampling: Not affected
Vulnerability Ghostwrite: Not affected
Vulnerability Indirect target selection: Not affected
Vulnerability Itlb multihit: Not affected
Vulnerability L1tf: Not affected
Vulnerability Mds: Not affected
Vulnerability Meltdown: Not affected
Vulnerability Mmio stale data: Not affected
Vulnerability Reg file data sampling: Not affected
Vulnerability Retbleed: Not affected
Vulnerability Spec rstack overflow: Mitigation; Safe RET
Vulnerability Spec store bypass: Mitigation; Speculative Store Bypass disabled via prctl
Vulnerability Spectre v1: Mitigation; usercopy/swapgs barriers and __user pointer sanitization
Vulnerability Spectre v2: Mitigation; Enhanced / Automatic IBRS; IBPB conditional; STIBP always-on; PBRSB-eIBRS Not affected; BHI Not affected
Vulnerability Srbds: Not affected
Vulnerability Tsa: Vulnerable: Clear CPU buffers attempted, no microcode
Vulnerability Tsx async abort: Not affected
Vulnerability Vmscape: Mitigation; IBPB before exit to userspace
Versions of relevant libraries:
[pip3] executorch==1.1.0
[pip3] numpy==2.4.2
[pip3] nvidia-cublas-cu12==12.8.4.1
[pip3] nvidia-cuda-cupti-cu12==12.8.90
[pip3] nvidia-cuda-nvrtc-cu12==12.8.93
[pip3] nvidia-cuda-runtime-cu12==12.8.90
[pip3] nvidia-cudnn-cu12==9.10.2.21
[pip3] nvidia-cufft-cu12==11.3.3.83
[pip3] nvidia-curand-cu12==10.3.9.90
[pip3] nvidia-cusolver-cu12==11.7.3.90
[pip3] nvidia-cusparse-cu12==12.5.8.93
[pip3] nvidia-cusparselt-cu12==0.7.1
[pip3] nvidia-nccl-cu12==2.27.5
[pip3] nvidia-nvjitlink-cu12==12.8.93
[pip3] nvidia-nvtx-cu12==12.8.90
[pip3] pytorch_tokenizers==1.1.0
[pip3] torch==2.10.0
[pip3] torchao==0.15.0
[pip3] torchvision==0.25.0
[pip3] triton==3.6.0
[conda] Could not collect