Nvbuf_utils cant free dmabuf when imported by cudaImportExternalMemory

when I create a NvBufferFd use NvBufferCreate(),then map it to a cuda buffer named ‘cuda_ptr’ using cudaImportExternalMemory() and cudaExternalMemoryGetMappedBuffer(). ‘cuda_ptr’ can pass to a cuda kernel to do some operations correctly. It seems that everything goes well. but when I want to release the memory allocated to the NvBuffer, No matter how i try it doesn’t work. i try to use cudaFree(cuda_ptr) or NvBufferDestroy(fd) or NvReleaseFd(fd) or some combinations of them. the memory still con’t be free unless i kill the process.
so anyone can give me some suggestion how to free memory in this case?

i will paste the test code i use follow. please ignore the log function and error-check function.

void test_func(){
    int ret = 0;
    int fd = -1;
    int cols = 1920 * 5 * 10, rows = 1080 * 5;  // alloc size is big so the memory change is significant
    ret = NvBufferCreate(&fd, cols, rows, NvBufferLayout_Pitch, NvBufferColorFormat_ABGR32);
    if (ret < 0) {
        BVA_ERROR("Failed to create NvBuffer:%d, for:%dx%d\n", ret, cols, rows);
    BVA_INFO("Create nv buffer fd:%d, for:%dx%d\n", fd, cols, rows);

    // 2. import external memory
    NvBufferParams params;
    memset(&params, 0, sizeof(params));
    NvBufferGetParams(fd, &params);
    BVA_INFO("NvBuffer pitch:%d\twidth:%d\theight:%d\n", params.pitch[0], params.width[0], params.height[0]);

    cudaExternalMemoryHandleDesc memHandleDesc;
    memset(&memHandleDesc, 0, sizeof(memHandleDesc));
    memHandleDesc.type = cudaExternalMemoryHandleTypeOpaqueFd;
    memHandleDesc.size = params.pitch[0] * params.height[0];
    memHandleDesc.handle.fd = fd;
    cudaExternalMemory_t extMem = nullptr;

    checkCudaErrors(cudaImportExternalMemory(&extMem, &memHandleDesc));
    BVA_INFO("cudaImportExternalMemory success\n");

    // 3. get dev_buf
    cudaExternalMemoryBufferDesc bufferDesc;
    memset(&bufferDesc, 0, sizeof(bufferDesc));
    bufferDesc.offset = 0;
    bufferDesc.size = memHandleDesc.size;
    void *dev_ptr = nullptr;
    checkCudaErrors(cudaExternalMemoryGetMappedBuffer(&dev_ptr, extMem, &bufferDesc));
    BVA_INFO("cudaExternalMemoryGetMappedBuffer success\n");

    // cuda kernel function using dev_ptr as input 

    // 4. free memory(any combinations of following oprations is not work)
    // 4.1
    BVA_INFO("cudaDestroyExternalMemory success\n");
    // 4.2
    if (dev_ptr) {
        dev_ptr = nullptr;
        BVA_INFO("cudaFree success\n");
    // 4.3
    // ret = NvReleaseFd(fd);
    // if (ret < 0) {
    //     BVA_ERROR("NvReleaseFd failed\n");
    // } else {
    //     BVA_INFO("NvReleaseFd success\n");
    // }
    // 4.4
    // ret = NvBufferDestroy(fd);
    // if (ret < 0) {
    //     BVA_ERROR("NvBufferDestroy failed\n");
    // } else {
    //     BVA_INFO("NvBufferDestroy success\n");
    // }


NvBufferCreate just maps the buffer into GPU accessible without memcpy.
The destroy will only release the “mapping” rather than buffer itself.

To free the memory completely, please release the original buffer after destroying the mapping.


hi,thanks for reply.
but i still confused about “release the original buffer” in your answer.
according to my understanding, in the code i paste before, i got 2 ways to operate the buffer, one is file descriptor fd, another is device pointer dev_ptr.
which API should I call to free the original memory? I already try the cudaFree, but no use.
plus,there is a error report “NVMAP_IOC_FREE failed: Bad file descriptor” when I call both NvBufferDestroy and cudaFree, although the return value is success. when i change the order of the calls,there always a same error report in the later functions. can you explain this?
thanks ~