ikwzm / udmabuf

User space mappable dma buffer device driver for Linux.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Uncached memory access for Core 1

darko31 opened this issue · comments

Hello ikwzm,

thank you for this very useful driver.
I'm using this driver for transferring data between PL and PS and also from Core 1 to Core 0 on Zynq 7000 device.
Core 0 is running Linux while Core 1 is running bare metal application in sort of AMP mode.
Sync mode is set to 1 so cache should be disabled. But, data read with udmabuf on Core 0 seems wrong, some data is good, some data is zero. It seems that cache is still enabled.
This is confirmed by running Xil_DCacheFlushRange on the baremetal app for that specific address, then data seems good.

I know this isn't primary use case for udmabuf. Can you maybe point out how to flush and invalidate cache from Core 0 Linux/udmabuf instead of flushing cache from bare metal app after every write.

Best regards,
Darko

Thank you for the issue.

Did you add O_SYNC when opening the device file?

    /* To disable CPU cache on the DMA buffer, */
    /* open udmabuf with the `O_SYNC` flag. */
    if ((fd  = open("/dev/udmabuf0", O_RDWR | O_SYNC)) != -1) {
        buf = mmap(NULL, buf_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
        /* Read/write access to the buffer */
        close(fd);
    }

Yes, this is the code for mapping udmabuf
` std::int32_t udmabuf_fd;
void *udmabuf_pointer;

/* https://github.com/ikwzm/udmabuf */
/* To enable CPU cache on the DMA buffer, */
/* open udmabuf without specifying the `O_SYNC` flag. */
/* Cache is disabled */
udmabuf_fd = open(UDMABUF_DEVICE_PATH, O_RDWR | O_SYNC);
if (udmabuf_fd < 0){
    LOG(FATAL) << "Unable to open udmabuf device!";
}

udmabuf_pointer = mmap(NULL, current_device.udmabuf_size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED, udmabuf_fd, 0);

if (udmabuf_pointer == MAP_FAILED){
    LOG(FATAL) << "Failed to mmap udmabuf";
}

return udmabuf_pointer;`

This seems to be an issue with Core 1 not being aware of caching attributes of udmabuf memory region. Note that bootarg parameter contains maxcpus=1, so that Linux initiates only one core, so that other one can be available for baremetal application.
Are you maybe aware of mechanism of flushing cache of Core 1 from Linux driver or userland?

Thank you

I'm sorry.
I don't know how to control cache for memory area secured by udmabuf from bare metal application running on Core1.

Ok, thank you, This issue can be closed then.

Hello, just a quick update. Using custom function MyXil_SetTlbAttributes from XAPP1078 in bare metal application on Core 1 I was able to disable cache and kernel panics were not occurring anymore on Core 0. Everything worked as expected.

More info at
https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18841653/XAPP1078+Latest+Information