Hello Guys, Turns out host controller's DMA alignment is often too relax, so two DMA buffers may cross same cache line easily, and trigger the warning of "cacheline tracking EEXIST, overlapping mappings aren't supported". The attached test code can trigger the warning immediately with CONFIG_DMA_API_DEBUG enabled when reading from one scsi disk which queue DMA alignment is 3. Thanks, Ming
#define _GNU_SOURCE #include <stdio.h> #include <fcntl.h> #include <string.h> #include <stdlib.h> #include <libaio.h> #include <errno.h> #include <unistd.h> int main(int argc, char *argv[]) { const char *outputfile=argv[1]; io_context_t ctx; int output_fd; const int nr = 4; struct iocb _io[nr]; struct iocb *io[16] = { &_io[0], &_io[1], &_io[2], &_io[3], }; struct io_event e[nr]; struct timespec timeout; int ret; char *content; unsigned size = 2*1024 * 1024; posix_memalign((void **)&content, 4096, nr * size + 512); memset(&ctx,0,sizeof(ctx)); if(io_setup(10, &ctx) != 0) { printf("io_setup error\n"); return -1; } if((output_fd = open(outputfile, O_DIRECT, 0644)) < 0) { perror("open error"); io_destroy(ctx); return -1; } io_prep_pread(io[0], output_fd, content + 4, size, 0); io_prep_pread(io[1], output_fd, content + size, size, size * 2); io_prep_pread(io[2], output_fd, content + size * 2, size, size * 4); io_prep_pread(io[3], output_fd, content + size * 3, size, size * 8); ret = io_submit(ctx, nr, io); if(ret != nr) { io_destroy(ctx); printf("io_submit error %d\n", ret); return -1; } while(1) { timeout.tv_sec=0; timeout.tv_nsec=500000000; if (io_getevents(ctx, nr, nr, e, &timeout) == nr) { close(output_fd); break; } printf("haven't done\n"); sleep(1); } io_destroy(ctx); return 0; }