| 1 | |
| 2 | |
| 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/map_benchmark.h>
|
| 14 |
|
| 15 | #define NSEC_PER_MSEC 1000000L
|
| 16 |
|
| 17 | static char *directions[] = {
|
| 18 | "BIDIRECTIONAL",
|
| 19 | "TO_DEVICE",
|
| 20 | "FROM_DEVICE",
|
| 21 | };
|
| 22 |
|
| 23 | static char *mode[] = {
|
| 24 | "SINGLE_MODE",
|
| 25 | "SG_MODE",
|
| 26 | };
|
| 27 |
|
| 28 | int main(int argc, char **argv)
|
| 29 | {
|
| 30 | struct map_benchmark map;
|
| 31 | int fd, opt;
|
| 32 |
|
| 33 | int threads = 1, seconds = 20, node = -1;
|
| 34 |
|
| 35 | int map_mode = DMA_MAP_BENCH_SINGLE_MODE;
|
| 36 |
|
| 37 | int bits = 32, xdelay = 0, dir = DMA_MAP_BIDIRECTIONAL;
|
| 38 |
|
| 39 | int granule = 1;
|
| 40 |
|
| 41 | int cmd = DMA_MAP_BENCHMARK;
|
| 42 |
|
| 43 | while ((opt = getopt(argc, argv, "t:s:n:b:d:x:g:m:")) != -1) {
|
| 44 | switch (opt) {
|
| 45 | case 't':
|
| 46 | threads = atoi(optarg);
|
| 47 | break;
|
| 48 | case 's':
|
| 49 | seconds = atoi(optarg);
|
| 50 | break;
|
| 51 | case 'n':
|
| 52 | node = atoi(optarg);
|
| 53 | break;
|
| 54 | case 'b':
|
| 55 | bits = atoi(optarg);
|
| 56 | break;
|
| 57 | case 'd':
|
| 58 | dir = atoi(optarg);
|
| 59 | break;
|
| 60 | case 'x':
|
| 61 | xdelay = atoi(optarg);
|
| 62 | break;
|
| 63 | case 'g':
|
| 64 | granule = atoi(optarg);
|
| 65 | break;
|
| 66 | case 'm':
|
| 67 | map_mode = atoi(optarg);
|
| 68 | break;
|
| 69 | default:
|
| 70 | return -1;
|
| 71 | }
|
| 72 | }
|
| 73 |
|
| 74 | if (map_mode < 0 || map_mode >= DMA_MAP_BENCH_MODE_MAX) {
|
| 75 | fprintf(stderr, "invalid map mode, SINGLE_MODE:%d, SG_MODE: %d\n",
|
| 76 | DMA_MAP_BENCH_SINGLE_MODE, DMA_MAP_BENCH_SG_MODE);
|
| 77 | exit(1);
|
| 78 | }
|
| 79 |
|
| 80 | if (threads <= 0 || threads > DMA_MAP_MAX_THREADS) {
|
| 81 | fprintf(stderr, "invalid number of threads, must be in 1-%d\n",
|
| 82 | DMA_MAP_MAX_THREADS);
|
| 83 | exit(1);
|
| 84 | }
|
| 85 |
|
| 86 | if (seconds <= 0 || seconds > DMA_MAP_MAX_SECONDS) {
|
| 87 | fprintf(stderr, "invalid number of seconds, must be in 1-%d\n",
|
| 88 | DMA_MAP_MAX_SECONDS);
|
| 89 | exit(1);
|
| 90 | }
|
| 91 |
|
| 92 | if (xdelay < 0 || xdelay > DMA_MAP_MAX_TRANS_DELAY) {
|
| 93 | fprintf(stderr, "invalid transmit delay, must be in 0-%ld\n",
|
| 94 | DMA_MAP_MAX_TRANS_DELAY);
|
| 95 | exit(1);
|
| 96 | }
|
| 97 |
|
| 98 |
|
| 99 | if (bits < 20 || bits > 64) {
|
| 100 | fprintf(stderr, "invalid dma mask bit, must be in 20-64\n");
|
| 101 | exit(1);
|
| 102 | }
|
| 103 |
|
| 104 | if (dir != DMA_MAP_BIDIRECTIONAL && dir != DMA_MAP_TO_DEVICE &&
|
| 105 | dir != DMA_MAP_FROM_DEVICE) {
|
| 106 | fprintf(stderr, "invalid dma direction\n");
|
| 107 | exit(1);
|
| 108 | }
|
| 109 |
|
| 110 | if (granule < 1 || granule > 1024) {
|
| 111 | fprintf(stderr, "invalid granule size\n");
|
| 112 | exit(1);
|
| 113 | }
|
| 114 |
|
| 115 | fd = open("/sys/kernel/debug/dma_map_benchmark", O_RDWR);
|
| 116 | if (fd == -1) {
|
| 117 | perror("open");
|
| 118 | exit(1);
|
| 119 | }
|
| 120 |
|
| 121 | memset(&map, 0, sizeof(map));
|
| 122 | map.seconds = seconds;
|
| 123 | map.threads = threads;
|
| 124 | map.node = node;
|
| 125 | map.dma_bits = bits;
|
| 126 | map.dma_dir = dir;
|
| 127 | map.dma_trans_ns = xdelay;
|
| 128 | map.granule = granule;
|
| 129 | map.map_mode = map_mode;
|
| 130 |
|
| 131 | if (ioctl(fd, cmd, &map)) {
|
| 132 | perror("ioctl");
|
| 133 | exit(1);
|
| 134 | }
|
| 135 |
|
| 136 | printf("dma mapping benchmark(%s): threads:%d seconds:%d node:%d dir:%s granule:%d\n",
|
| 137 | mode[map_mode], threads, seconds, node, directions[dir], granule);
|
| 138 | printf("average map latency(us):%.1f standard deviation:%.1f\n",
|
| 139 | map.avg_map_100ns/10.0, map.map_stddev/10.0);
|
| 140 | printf("average unmap latency(us):%.1f standard deviation:%.1f\n",
|
| 141 | map.avg_unmap_100ns/10.0, map.unmap_stddev/10.0);
|
| 142 |
|
| 143 | return 0;
|
| 144 | }
|