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; }