From: Qinxin Xia Date: Wed, 25 Feb 2026 09:38:00 +0000 (+0800) Subject: tools/dma: Add dma_map_sg support X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a54302ccfd38afba7b297566f0d414b961ca97bf;p=thirdparty%2Fkernel%2Flinux.git tools/dma: Add dma_map_sg support Support for dma_map_sg, add option '-m' to distinguish mode. i) Users can set option '-m' to select mode: DMA_MAP_BENCH_SINGLE_MODE=0, DMA_MAP_BENCH_SG_MODE:=1 (The mode is also show in the test result). ii) Users can set option '-g' to set sg_nents (total count of entries in scatterlist) the maximum number is 1024. Each of sg buf size is PAGE_SIZE. e.g [root@localhost]# ./dma_map_benchmark -m 1 -g 8 -t 8 -s 30 -d 2 dma mapping mode: DMA_MAP_BENCH_SG_MODE dma mapping benchmark: threads:8 seconds:30 node:-1 dir:FROM_DEVICE granule/sg_nents: 8 average map latency(us):1.4 standard deviation:0.3 average unmap latency(us):1.3 standard deviation:0.3 [root@localhost]# ./dma_map_benchmark -m 0 -g 8 -t 8 -s 30 -d 2 dma mapping mode: DMA_MAP_BENCH_SINGLE_MODE dma mapping benchmark: threads:8 seconds:30 node:-1 dir:FROM_DEVICE granule/sg_nents: 8 average map latency(us):1.0 standard deviation:0.3 average unmap latency(us):1.3 standard deviation:0.5 Reviewed-by: Barry Song Signed-off-by: Qinxin Xia Signed-off-by: Marek Szyprowski Link: https://lore.kernel.org/r/20260225093800.3625054-4-xiaqinxin@huawei.com --- diff --git a/tools/dma/dma_map_benchmark.c b/tools/dma/dma_map_benchmark.c index dd0ed528e6dfc..eab0ac611a23a 100644 --- a/tools/dma/dma_map_benchmark.c +++ b/tools/dma/dma_map_benchmark.c @@ -20,12 +20,19 @@ static char *directions[] = { "FROM_DEVICE", }; +static char *mode[] = { + "SINGLE_MODE", + "SG_MODE", +}; + int main(int argc, char **argv) { struct map_benchmark map; int fd, opt; /* default single thread, run 20 seconds on NUMA_NO_NODE */ int threads = 1, seconds = 20, node = -1; + /* default single map mode */ + int map_mode = DMA_MAP_BENCH_SINGLE_MODE; /* default dma mask 32bit, bidirectional DMA */ int bits = 32, xdelay = 0, dir = DMA_MAP_BIDIRECTIONAL; /* default granule 1 PAGESIZE */ @@ -33,7 +40,7 @@ int main(int argc, char **argv) int cmd = DMA_MAP_BENCHMARK; - while ((opt = getopt(argc, argv, "t:s:n:b:d:x:g:")) != -1) { + while ((opt = getopt(argc, argv, "t:s:n:b:d:x:g:m:")) != -1) { switch (opt) { case 't': threads = atoi(optarg); @@ -56,11 +63,20 @@ int main(int argc, char **argv) case 'g': granule = atoi(optarg); break; + case 'm': + map_mode = atoi(optarg); + break; default: return -1; } } + if (map_mode < 0 || map_mode >= DMA_MAP_BENCH_MODE_MAX) { + fprintf(stderr, "invalid map mode, SINGLE_MODE:%d, SG_MODE: %d\n", + DMA_MAP_BENCH_SINGLE_MODE, DMA_MAP_BENCH_SG_MODE); + exit(1); + } + if (threads <= 0 || threads > DMA_MAP_MAX_THREADS) { fprintf(stderr, "invalid number of threads, must be in 1-%d\n", DMA_MAP_MAX_THREADS); @@ -110,14 +126,15 @@ int main(int argc, char **argv) map.dma_dir = dir; map.dma_trans_ns = xdelay; map.granule = granule; + map.map_mode = map_mode; if (ioctl(fd, cmd, &map)) { perror("ioctl"); exit(1); } - printf("dma mapping benchmark: threads:%d seconds:%d node:%d dir:%s granule: %d\n", - threads, seconds, node, directions[dir], granule); + printf("dma mapping benchmark(%s): threads:%d seconds:%d node:%d dir:%s granule:%d\n", + mode[map_mode], threads, seconds, node, directions[dir], granule); printf("average map latency(us):%.1f standard deviation:%.1f\n", map.avg_map_100ns/10.0, map.map_stddev/10.0); printf("average unmap latency(us):%.1f standard deviation:%.1f\n",