cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dma_map_benchmark.c (2887B)


      1// SPDX-License-Identifier: GPL-2.0-only
      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/types.h>
     14#include <linux/map_benchmark.h>
     15
     16#define NSEC_PER_MSEC	1000000L
     17
     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	char *p;
     37
     38	while ((opt = getopt(argc, argv, "t:s:n:b:d:x:g:")) != -1) {
     39		switch (opt) {
     40		case 't':
     41			threads = atoi(optarg);
     42			break;
     43		case 's':
     44			seconds = atoi(optarg);
     45			break;
     46		case 'n':
     47			node = atoi(optarg);
     48			break;
     49		case 'b':
     50			bits = atoi(optarg);
     51			break;
     52		case 'd':
     53			dir = atoi(optarg);
     54			break;
     55		case 'x':
     56			xdelay = atoi(optarg);
     57			break;
     58		case 'g':
     59			granule = atoi(optarg);
     60			break;
     61		default:
     62			return -1;
     63		}
     64	}
     65
     66	if (threads <= 0 || threads > DMA_MAP_MAX_THREADS) {
     67		fprintf(stderr, "invalid number of threads, must be in 1-%d\n",
     68			DMA_MAP_MAX_THREADS);
     69		exit(1);
     70	}
     71
     72	if (seconds <= 0 || seconds > DMA_MAP_MAX_SECONDS) {
     73		fprintf(stderr, "invalid number of seconds, must be in 1-%d\n",
     74			DMA_MAP_MAX_SECONDS);
     75		exit(1);
     76	}
     77
     78	if (xdelay < 0 || xdelay > DMA_MAP_MAX_TRANS_DELAY) {
     79		fprintf(stderr, "invalid transmit delay, must be in 0-%ld\n",
     80			DMA_MAP_MAX_TRANS_DELAY);
     81		exit(1);
     82	}
     83
     84	/* suppose the mininum DMA zone is 1MB in the world */
     85	if (bits < 20 || bits > 64) {
     86		fprintf(stderr, "invalid dma mask bit, must be in 20-64\n");
     87		exit(1);
     88	}
     89
     90	if (dir != DMA_MAP_BIDIRECTIONAL && dir != DMA_MAP_TO_DEVICE &&
     91			dir != DMA_MAP_FROM_DEVICE) {
     92		fprintf(stderr, "invalid dma direction\n");
     93		exit(1);
     94	}
     95
     96	if (granule < 1 || granule > 1024) {
     97		fprintf(stderr, "invalid granule size\n");
     98		exit(1);
     99	}
    100
    101	fd = open("/sys/kernel/debug/dma_map_benchmark", O_RDWR);
    102	if (fd == -1) {
    103		perror("open");
    104		exit(1);
    105	}
    106
    107	memset(&map, 0, sizeof(map));
    108	map.seconds = seconds;
    109	map.threads = threads;
    110	map.node = node;
    111	map.dma_bits = bits;
    112	map.dma_dir = dir;
    113	map.dma_trans_ns = xdelay;
    114	map.granule = granule;
    115
    116	if (ioctl(fd, cmd, &map)) {
    117		perror("ioctl");
    118		exit(1);
    119	}
    120
    121	printf("dma mapping benchmark: threads:%d seconds:%d node:%d dir:%s granule: %d\n",
    122			threads, seconds, node, dir[directions], granule);
    123	printf("average map latency(us):%.1f standard deviation:%.1f\n",
    124			map.avg_map_100ns/10.0, map.map_stddev/10.0);
    125	printf("average unmap latency(us):%.1f standard deviation:%.1f\n",
    126			map.avg_unmap_100ns/10.0, map.unmap_stddev/10.0);
    127
    128	return 0;
    129}