Path: blob/master/tools/testing/selftests/dma/dma_map_benchmark.c
26302 views
// SPDX-License-Identifier: GPL-2.0-only1/*2* Copyright (C) 2020 HiSilicon Limited.3*/45#include <fcntl.h>6#include <stdio.h>7#include <stdlib.h>8#include <string.h>9#include <unistd.h>10#include <sys/ioctl.h>11#include <sys/mman.h>12#include <linux/types.h>13#include <linux/map_benchmark.h>1415#define NSEC_PER_MSEC 1000000L1617static char *directions[] = {18"BIDIRECTIONAL",19"TO_DEVICE",20"FROM_DEVICE",21};2223int main(int argc, char **argv)24{25struct map_benchmark map;26int fd, opt;27/* default single thread, run 20 seconds on NUMA_NO_NODE */28int threads = 1, seconds = 20, node = -1;29/* default dma mask 32bit, bidirectional DMA */30int bits = 32, xdelay = 0, dir = DMA_MAP_BIDIRECTIONAL;31/* default granule 1 PAGESIZE */32int granule = 1;3334int cmd = DMA_MAP_BENCHMARK;3536while ((opt = getopt(argc, argv, "t:s:n:b:d:x:g:")) != -1) {37switch (opt) {38case 't':39threads = atoi(optarg);40break;41case 's':42seconds = atoi(optarg);43break;44case 'n':45node = atoi(optarg);46break;47case 'b':48bits = atoi(optarg);49break;50case 'd':51dir = atoi(optarg);52break;53case 'x':54xdelay = atoi(optarg);55break;56case 'g':57granule = atoi(optarg);58break;59default:60return -1;61}62}6364if (threads <= 0 || threads > DMA_MAP_MAX_THREADS) {65fprintf(stderr, "invalid number of threads, must be in 1-%d\n",66DMA_MAP_MAX_THREADS);67exit(1);68}6970if (seconds <= 0 || seconds > DMA_MAP_MAX_SECONDS) {71fprintf(stderr, "invalid number of seconds, must be in 1-%d\n",72DMA_MAP_MAX_SECONDS);73exit(1);74}7576if (xdelay < 0 || xdelay > DMA_MAP_MAX_TRANS_DELAY) {77fprintf(stderr, "invalid transmit delay, must be in 0-%ld\n",78DMA_MAP_MAX_TRANS_DELAY);79exit(1);80}8182/* suppose the mininum DMA zone is 1MB in the world */83if (bits < 20 || bits > 64) {84fprintf(stderr, "invalid dma mask bit, must be in 20-64\n");85exit(1);86}8788if (dir != DMA_MAP_BIDIRECTIONAL && dir != DMA_MAP_TO_DEVICE &&89dir != DMA_MAP_FROM_DEVICE) {90fprintf(stderr, "invalid dma direction\n");91exit(1);92}9394if (granule < 1 || granule > 1024) {95fprintf(stderr, "invalid granule size\n");96exit(1);97}9899fd = open("/sys/kernel/debug/dma_map_benchmark", O_RDWR);100if (fd == -1) {101perror("open");102exit(1);103}104105memset(&map, 0, sizeof(map));106map.seconds = seconds;107map.threads = threads;108map.node = node;109map.dma_bits = bits;110map.dma_dir = dir;111map.dma_trans_ns = xdelay;112map.granule = granule;113114if (ioctl(fd, cmd, &map)) {115perror("ioctl");116exit(1);117}118119printf("dma mapping benchmark: threads:%d seconds:%d node:%d dir:%s granule: %d\n",120threads, seconds, node, dir[directions], granule);121printf("average map latency(us):%.1f standard deviation:%.1f\n",122map.avg_map_100ns/10.0, map.map_stddev/10.0);123printf("average unmap latency(us):%.1f standard deviation:%.1f\n",124map.avg_unmap_100ns/10.0, map.unmap_stddev/10.0);125126return 0;127}128129130