Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 31 additions & 11 deletions .github/workflows/rocjitsu-corpus-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -214,35 +214,47 @@ jobs:
ROCMINFO=RocminfoTest
RCCL_DAEMON=RcclDaemonTest
EXCLUDED_TESTS="${ROCMINFO}|${RCCL_DAEMON}"
SANITIZER_EXCLUDED_TESTS=(
"HsaTest\.InitSucceeded"
"HsaTest\.GpuAgentFound"
COMMON_SANITIZER_EXCLUDED_TESTS=(
# The hardware-backed tools-hook test cannot initialize ROCR when
# the launcher and hook use a sanitizer-instrumented process image.
"HsaHooksTest\.TranslateGfx950Mfma16x16ThroughToolsLib"
"Cdna4ToCdna3SimulatedDispatchTest\..*"
"Cdna4ToCdna3DbtGuestTest\..*"
"DaemonTest\.LoggingPlugin"
"BfeRegressionTest\.ThreadIdxY"
"LoggingTest\.dispatch_logged"
"CvtNarrow\.AllTests"
"RaceTest\..*"
)
CLANG_ASAN_UBSAN_EXCLUDED_TESTS=(
"${COMMON_SANITIZER_EXCLUDED_TESTS[@]}"
# Direct HIP clients hang in the Clang sanitizer lane. The daemon
# variants complete their functional checks, but the unsymbolized
# ROCr library reports process-exit allocations that cannot be
# suppressed without hiding all leaks originating in ROCr.
"HipMemcpyTest\.RoundTripFloat"
"HipMemcpyTest\.RoundTripInt"
"HipMemcpyTest\.DeviceToDevice"
"HipVectorAddTest\.CorrectResult"
"DaemonTest\.HipVectorAdd"
"DaemonTest\.HipMemcpyRoundTripFloat"
"DaemonTest\.HipMemcpyRoundTripInt"
"DaemonTest\.HipMemcpyDeviceToDevice"
"DaemonTest\.TwoIndependentClients"
"DaemonTest\.LoggingPlugin"
"BfeRegressionTest\.ThreadIdxY"
"LoggingTest\.dispatch_logged"
"CvtNarrow\.AllTests"
"RaceTest\..*"
)
TSAN_EXCLUDED_TESTS=(
"${SANITIZER_EXCLUDED_TESTS[@]}"
"${COMMON_SANITIZER_EXCLUDED_TESTS[@]}"
# Hardware dispatch reports a TSan race while ROCr tears down its
# async-event bookkeeping, outside rocjitsu-owned code.
"HsaTranslateTest\.TranslateAndDispatchVectorAdd"
"HsaTranslateTest\.TranslateAndDispatchMfma16x16"
# Direct HIP test discovery initializes the instrumented ROCr client,
# which reports a ConcurrentAsyncEvents race; vector add also exposes
# unsynchronized simulator/client buffer access. The daemon variants
# use the separately synchronized RPC path and remain enabled.
"HipMemcpyTest\.RoundTripFloat"
"HipMemcpyTest\.RoundTripInt"
"HipMemcpyTest\.DeviceToDevice"
"HipVectorAddTest\.CorrectResult"
# This test has a five-second wall-clock assertion that becomes
# load-sensitive at the TSan job's CI-level parallelism.
"DaemonApi\.FullListenerQueueDoesNotBlockOrRemoveSocket"
Expand All @@ -251,13 +263,21 @@ jobs:
TEST_REGEX="${{ matrix.test_regex }}"
CMAKE_CONFIG_FLAGS=()
if [[ "${{ matrix.enable_asan }}" == "1" && "${{ matrix.enable_ubsan }}" == "1" ]]; then
EXCLUDED_TESTS="${EXCLUDED_TESTS}|$(IFS='|'; echo "${SANITIZER_EXCLUDED_TESTS[*]}")"
if [[ -z "${{ matrix.cxx_compiler }}" || "${{ matrix.cxx_compiler }}" == *clang* ]]; then
EXCLUDED_TESTS="${EXCLUDED_TESTS}|$(IFS='|'; echo "${CLANG_ASAN_UBSAN_EXCLUDED_TESTS[*]}")"
else
EXCLUDED_TESTS="${EXCLUDED_TESTS}|$(IFS='|'; echo "${COMMON_SANITIZER_EXCLUDED_TESTS[*]}")"
fi
CMAKE_CONFIG_FLAGS+=(
-DCMAKE_C_FLAGS_RELWITHDEBINFO="-O2 -g"
-DCMAKE_CXX_FLAGS_RELWITHDEBINFO="-O2 -g"
)
fi
if [[ "${{ matrix.enable_tsan }}" == "1" ]]; then
# The CP reads a stable MAP_SHARED alias rather than the client's
# virtual address. TSan keys shadow state by address and therefore
# cannot validate the store/load synchronization across those two
# aliases; these tests cover lifecycle and teardown races only.
EXCLUDED_TESTS="${EXCLUDED_TESTS}|$(IFS='|'; echo "${TSAN_EXCLUDED_TESTS[*]}")"
fi
if [[ -n "${{ matrix.c_compiler }}" ]]; then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1136,6 +1136,14 @@ bool GuestKfd::is_doorbell_range(const void *addr, size_t length) const {
return execution_driver_ && execution_driver_->is_doorbell_range(addr, length);
}

void *GuestKfd::mmap_replacing_client_doorbell_views(void *addr, size_t length, int prot, int flags,
int fd, off_t offset) {
if (execution_driver_)
return execution_driver_->mmap_replacing_client_doorbell_views(addr, length, prot, flags, fd,
offset);
return libc_passthrough().mmap(addr, length, prot, flags, fd, offset);
}

bool GuestKfd::handles_drm_render_minor(uint32_t minor) const {
if (ready_.load(std::memory_order_acquire) && minor == guest_.drm_render_minor)
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ class GuestKfd : public LinuxKfd {
/// @brief Return true if a mapping range overlaps a protected doorbell.
[[nodiscard]] bool is_doorbell_range(const void *addr, size_t length) const override;

/// @brief Forward fixed-map replacement to the simulated execution driver when present.
void *mmap_replacing_client_doorbell_views(void *addr, size_t length, int prot, int flags, int fd,
off_t offset) override;

/// @brief Return true when @p minor is the configured guest render node.
[[nodiscard]] bool handles_drm_render_minor(uint32_t minor) const override;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2966,6 +2966,10 @@ RJ_INTERPOSER_EXPORT void *mmap(void *addr, size_t length, int prot, int flags,
}
}
}
if ((flags & MAP_FIXED) && addr) {
if (auto *driver = InterposerContext::ctx.driver())
return driver->mmap_replacing_client_doorbell_views(addr, length, prot, flags, fd, offset);
}
return InterposerContext::real().mmap(addr, length, prot, flags, fd, offset);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,19 @@ class KfdProcess {
public:
/// @brief Per-GPU state within a process.
struct PerGpuState {
void *doorbell_page = nullptr;
/// @brief One live client mapping of the canonical doorbell backing.
struct DoorbellView {
void *page = nullptr;
uint64_t gpu_va = 0;
};

/// @brief Canonical shared backing retained for the process lifetime.
int doorbell_memfd = -1;
/// @brief Every client doorbell view still owned by the mapping layer.
std::vector<DoorbellView> doorbell_views;
/// @brief Stable driver-side alias used exclusively by the command processor.
void *doorbell_monitor_page = nullptr;
size_t doorbell_page_size = 0;
uint64_t doorbell_gpu_va = 0;
uint64_t next_doorbell_offset = 0;
std::vector<uint32_t> free_doorbell_offsets;
uint64_t scratch_backing_va = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ class LinuxKfd : public Driver {
/// @brief Return true if a memory range is a KFD doorbell mapping.
[[nodiscard]] virtual bool is_doorbell_range(const void *addr, size_t length) const = 0;

/// @brief Perform an ordinary fixed mmap while retiring replaced client doorbell views.
/// @details Simulator-backed drivers remove overlapping client views from KFD ownership before
/// the mapping is replaced. Drivers without simulated execution pass the mmap through unchanged.
virtual void *mmap_replacing_client_doorbell_views(void *addr, size_t length, int prot, int flags,
int fd, off_t offset) = 0;

/// @brief Return true if this driver should synthesize /dev/dri/renderD@p minor.
[[nodiscard]] virtual bool handles_drm_render_minor(uint32_t minor) const = 0;

Expand Down
Loading
Loading