brintos

brintos / linux-shallow public Read only

0
0
Text · 2.8 KiB · b12f1f9 Raw
129 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (C) 2020 HiSilicon Limited.4 */5 6#include <fcntl.h>7#include <stdio.h>8#include <stdlib.h>9#include <string.h>10#include <unistd.h>11#include <sys/ioctl.h>12#include <sys/mman.h>13#include <linux/types.h>14#include <linux/map_benchmark.h>15 16#define NSEC_PER_MSEC	1000000L17 18static char *directions[] = {19	"BIDIRECTIONAL",20	"TO_DEVICE",21	"FROM_DEVICE",22};23 24int main(int argc, char **argv)25{26	struct map_benchmark map;27	int fd, opt;28	/* default single thread, run 20 seconds on NUMA_NO_NODE */29	int threads = 1, seconds = 20, node = -1;30	/* default dma mask 32bit, bidirectional DMA */31	int bits = 32, xdelay = 0, dir = DMA_MAP_BIDIRECTIONAL;32	/* default granule 1 PAGESIZE */33	int granule = 1;34 35	int cmd = DMA_MAP_BENCHMARK;36 37	while ((opt = getopt(argc, argv, "t:s:n:b:d:x:g:")) != -1) {38		switch (opt) {39		case 't':40			threads = atoi(optarg);41			break;42		case 's':43			seconds = atoi(optarg);44			break;45		case 'n':46			node = atoi(optarg);47			break;48		case 'b':49			bits = atoi(optarg);50			break;51		case 'd':52			dir = atoi(optarg);53			break;54		case 'x':55			xdelay = atoi(optarg);56			break;57		case 'g':58			granule = atoi(optarg);59			break;60		default:61			return -1;62		}63	}64 65	if (threads <= 0 || threads > DMA_MAP_MAX_THREADS) {66		fprintf(stderr, "invalid number of threads, must be in 1-%d\n",67			DMA_MAP_MAX_THREADS);68		exit(1);69	}70 71	if (seconds <= 0 || seconds > DMA_MAP_MAX_SECONDS) {72		fprintf(stderr, "invalid number of seconds, must be in 1-%d\n",73			DMA_MAP_MAX_SECONDS);74		exit(1);75	}76 77	if (xdelay < 0 || xdelay > DMA_MAP_MAX_TRANS_DELAY) {78		fprintf(stderr, "invalid transmit delay, must be in 0-%ld\n",79			DMA_MAP_MAX_TRANS_DELAY);80		exit(1);81	}82 83	/* suppose the mininum DMA zone is 1MB in the world */84	if (bits < 20 || bits > 64) {85		fprintf(stderr, "invalid dma mask bit, must be in 20-64\n");86		exit(1);87	}88 89	if (dir != DMA_MAP_BIDIRECTIONAL && dir != DMA_MAP_TO_DEVICE &&90			dir != DMA_MAP_FROM_DEVICE) {91		fprintf(stderr, "invalid dma direction\n");92		exit(1);93	}94 95	if (granule < 1 || granule > 1024) {96		fprintf(stderr, "invalid granule size\n");97		exit(1);98	}99 100	fd = open("/sys/kernel/debug/dma_map_benchmark", O_RDWR);101	if (fd == -1) {102		perror("open");103		exit(1);104	}105 106	memset(&map, 0, sizeof(map));107	map.seconds = seconds;108	map.threads = threads;109	map.node = node;110	map.dma_bits = bits;111	map.dma_dir = dir;112	map.dma_trans_ns = xdelay;113	map.granule = granule;114 115	if (ioctl(fd, cmd, &map)) {116		perror("ioctl");117		exit(1);118	}119 120	printf("dma mapping benchmark: threads:%d seconds:%d node:%d dir:%s granule: %d\n",121			threads, seconds, node, dir[directions], granule);122	printf("average map latency(us):%.1f standard deviation:%.1f\n",123			map.avg_map_100ns/10.0, map.map_stddev/10.0);124	printf("average unmap latency(us):%.1f standard deviation:%.1f\n",125			map.avg_unmap_100ns/10.0, map.unmap_stddev/10.0);126 127	return 0;128}129