[Profiler] Add support for SMB/CIFS#8769
Conversation
BenchmarksBenchmark execution time: 2026-06-22 15:54:43 Comparing candidate commit f85496e in PR branch Found 0 performance improvements and 0 performance regressions! Performance is the same for 72 metrics, 0 unstable metrics, 62 known flaky benchmarks, 64 flaky benchmarks without significant changes.
|
Execution-Time Benchmarks Report ⏱️Execution-time results for samples comparing This PR (8769) and master. ✅ No regressions detected - check the details below Full Metrics ComparisonFakeDbCommand
HttpMessageHandler
Comparison explanationExecution-time benchmarks measure the whole time it takes to execute a program, and are intended to measure the one-off costs. Cases where the execution time results for the PR are worse than latest master results are highlighted in **red**. The following thresholds were used for comparing the execution times:
Note that these results are based on a single point-in-time result for each branch. For full results, see the dashboard. Graphs show the p99 interval based on the mean and StdDev of the test run, as well as the mean value of the run (shown as a diamond below the graph). Duration chartsFakeDbCommand (.NET Framework 4.8)gantt
title Execution time (ms) FakeDbCommand (.NET Framework 4.8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8769) - mean (70ms) : 68, 72
master - mean (72ms) : 68, 76
section Bailout
This PR (8769) - mean (76ms) : 71, 80
master - mean (77ms) : 73, 80
section CallTarget+Inlining+NGEN
This PR (8769) - mean (1,079ms) : 1033, 1124
master - mean (1,078ms) : 1036, 1120
FakeDbCommand (.NET Core 3.1)gantt
title Execution time (ms) FakeDbCommand (.NET Core 3.1)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8769) - mean (108ms) : 106, 111
master - mean (112ms) : 107, 118
section Bailout
This PR (8769) - mean (114ms) : 107, 120
master - mean (112ms) : 107, 117
section CallTarget+Inlining+NGEN
This PR (8769) - mean (770ms) : 749, 791
master - mean (774ms) : 752, 796
FakeDbCommand (.NET 6)gantt
title Execution time (ms) FakeDbCommand (.NET 6)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8769) - mean (97ms) : 93, 102
master - mean (99ms) : 95, 104
section Bailout
This PR (8769) - mean (100ms) : 95, 106
master - mean (99ms) : 96, 102
section CallTarget+Inlining+NGEN
This PR (8769) - mean (934ms) : 888, 981
master - mean (935ms) : 897, 973
FakeDbCommand (.NET 8)gantt
title Execution time (ms) FakeDbCommand (.NET 8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8769) - mean (95ms) : 92, 98
master - mean (95ms) : 92, 98
section Bailout
This PR (8769) - mean (95ms) : 93, 98
master - mean (98ms) : 92, 104
section CallTarget+Inlining+NGEN
This PR (8769) - mean (813ms) : 780, 847
master - mean (812ms) : 779, 846
HttpMessageHandler (.NET Framework 4.8)gantt
title Execution time (ms) HttpMessageHandler (.NET Framework 4.8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8769) - mean (202ms) : 197, 208
master - mean (202ms) : 195, 209
section Bailout
This PR (8769) - mean (206ms) : 201, 211
master - mean (206ms) : 199, 213
section CallTarget+Inlining+NGEN
This PR (8769) - mean (1,212ms) : 1174, 1249
master - mean (1,203ms) : 1162, 1245
HttpMessageHandler (.NET Core 3.1)gantt
title Execution time (ms) HttpMessageHandler (.NET Core 3.1)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8769) - mean (287ms) : 280, 293
master - mean (286ms) : 278, 294
section Bailout
This PR (8769) - mean (290ms) : 284, 296
master - mean (290ms) : 283, 298
section CallTarget+Inlining+NGEN
This PR (8769) - mean (968ms) : 949, 987
master - mean (966ms) : 947, 985
HttpMessageHandler (.NET 6)gantt
title Execution time (ms) HttpMessageHandler (.NET 6)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8769) - mean (284ms) : 276, 292
master - mean (283ms) : 276, 290
section Bailout
This PR (8769) - mean (286ms) : 278, 293
master - mean (282ms) : 278, 287
section CallTarget+Inlining+NGEN
This PR (8769) - mean (1,173ms) : 1135, 1212
master - mean (1,169ms) : 1121, 1218
HttpMessageHandler (.NET 8)gantt
title Execution time (ms) HttpMessageHandler (.NET 8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8769) - mean (282ms) : 274, 290
master - mean (282ms) : 273, 290
section Bailout
This PR (8769) - mean (282ms) : 277, 288
master - mean (281ms) : 272, 289
section CallTarget+Inlining+NGEN
This PR (8769) - mean (1,043ms) : 1002, 1084
master - mean (1,043ms) : 996, 1089
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
This comment has been minimized.
This comment has been minimized.
7c7d5e6 to
4c7f4f8
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4c7f4f8aba
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
Summary of changes
Wraps a set of libc filesystem functions in the Linux API wrapper (
LD_PRELOADshim) with retry-on-EINTRlogic, so that the Continuous Profiler'sSIGUSR1stack-sampling signal can no longer disrupt filesystem operations on CIFS/SMB mounts.A new file
filesystem_operations.cis added toDatadog.Linux.ApiWrapper, reusing the same shared-memory handshake + retry pattern already used bysocket_operations.c. The wrapped functions are:read,write,pread,pwrite,stat,lstat,fstatat(plus the legacy glibc__xstat/__lxstat/__fxstatatvariants), and the variadicopen/openat.Reason for change
A customer reported that enabling .NET profiling caused 10+ minute delays when their app accessed files on an SMB/CIFS network share, with response times dropping back to ~3 seconds when profiling was disabled.
Root cause: the profiler sends
SIGUSR1to threads to capture stacks. The kernel CIFS driver performs a Kerberos (re)authentication handshake against the KDC when a session/ticket expires (the ~2-hour cycle matches the Kerberos ticket renewal window). WhenSIGUSR1interrupts a filesystem syscall during that handshake, the CIFS driver internally convertsERESTARTSYStoEINTRbefore returning to userspace. Because the syscall surfaces asEINTR(notERESTARTSYS), the kernel's automaticSA_RESTARTmechanism — which the profiler's handler sets — does not restart the call. The failed operation then forces a full Kerberos re-auth, producing the multi-minute stalls.The existing counter-based wrapping (
functions_to_wrap.c) only prevents a stack walk; it does not retry the interrupted call, so it is insufficient here. The retry-based pattern fromsocket_operations.cis the correct fix.Implementation details
filesystem_operations.cdefines a localWRAPPED_FUNCTIONmacro (mirroringsocket_operations.c) that, for each wrapped function:__dd_dlsym(RTLD_NEXT, ...)(also resolved eagerly in a__attribute__((constructor))).volatile int interrupted_by_profilerflag through__dd_set_shared_memory(&flag)so the profiler treats the thread as non-interruptible (CanBeInterrupted()returns false while inside the wrapper).do/whileloop, retrying only whileis_interrupted_by_profiler(rc, errno, flag)is true (i.e.rc == -1 && errno == EINTR && flag != 0).__dd_set_shared_memory(NULL)) before returning.open/openatare variadic (optionalmode_twhenO_CREAT/O_TMPFILEis set), so they cannot use the macro and are implemented manually — extractingmodeviava_argonly when those flags are present, then applying the same retry loop.O_TMPFILEis guarded with#ifdeffor portability.stat/lstat/fstatatare inline header functions that call__xstat/__lxstat/__fxstatat, so those symbols are wrapped as well. They are harmless no-ops on musl, where apps callstatdirectly.closeis intentionally not wrapped: on Linuxclose()releases the fd even when it returnsEINTR, so retrying risks operating on a reused fd, andclosedoes not trigger Kerberos re-auth.CMakeLists.txtaddsfilesystem_operations.cto theDatadog.Linux.ApiWrappershared library.Test coverage
WrappedFunctions.cpp(Datadog.Linux.ApiWrapper.Tests) is extended to assert that each newly wrapped symbol is resolved by the dynamic loader toDatadog.Linux.ApiWrapper.x64.so— i.e. our wrapper is actually intercepting the call. New entries:open,openat,read,write,pread,pwrite, andstat/lstat/fstatatplus__xstat/__lxstat/__fxstatat.dlsym(RTLD_DEFAULT, "stat")rather than(void*)::stat, because on glibc < 2.33(void*)::statwould bind to the inline header function instead of the exported wrapper.DD_ALPINE).Other details
recv/sendalready pay insocket_operations.c. Negligible for local FS calls (microseconds) and dwarfed by CIFS latency.fsync/fdatasync,readv/writev, and directory-listing calls (getdents64/readdir) are not wrapped for now and can be added later if needed.SA_RESTARTset in production, local FS ops don't naturally produceEINTR, so the native unit test plus the LD_PRELOAD resolution check are the practical regression guards.