From bc816eeccb8a4f82e9547afe7ee6ed73fdcc925d Mon Sep 17 00:00:00 2001 From: Filip Leonarski Date: Thu, 10 Sep 2026 07:25:57 +0200 Subject: [PATCH] preprocessing: a buffer someone else page-locked is already what we wanted The uncompressed-image upload page-locks the caller's bytes, which is right when the caller allocated them for us and wrong when it did not: the online receiver registers its image buffer once and hands out ranges inside it, and registering a range a second time is an error rather than a no-op, so the first frame aborted the collection. An already-registered range needs nothing done to it - the upload is a DMA either way - and it is not ours to unregister when this object is destroyed, so it is deliberately not remembered. Co-Authored-By: Claude Opus 5 (1M context) --- .../image_preprocessing/ImagePreprocessorGPU.cu | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/image_analysis/image_preprocessing/ImagePreprocessorGPU.cu b/image_analysis/image_preprocessing/ImagePreprocessorGPU.cu index 643058cb6..a40ff94bb 100644 --- a/image_analysis/image_preprocessing/ImagePreprocessorGPU.cu +++ b/image_analysis/image_preprocessing/ImagePreprocessorGPU.cu @@ -352,7 +352,16 @@ void ImagePreprocessorGPU::PinInputRegion(const void *ptr, size_t bytes) { cuda_err(cudaHostUnregister(const_cast(pinned_input))); pinned_input = nullptr; pinned_input_bytes = 0; - cuda_err(cudaHostRegister(const_cast(ptr), bytes, cudaHostRegisterDefault)); + // The buffer may already be page-locked by whoever owns it - the receiver registers its image + // buffer once and hands out ranges inside it - and registering a range twice is an error rather + // than a no-op. There is nothing to do in that case: the upload is already a DMA, and the + // region is not ours to unregister later, so it is deliberately not remembered. + const auto err = cudaHostRegister(const_cast(ptr), bytes, cudaHostRegisterDefault); + if (err == cudaErrorHostMemoryAlreadyRegistered) { + cudaGetLastError(); + return; + } + cuda_err(err); pinned_input = ptr; pinned_input_bytes = bytes; }