hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/tools/testing/selftests/vm/gup_benchmark.c
....@@ -15,9 +15,19 @@
1515 #define PAGE_SIZE sysconf(_SC_PAGESIZE)
1616
1717 #define GUP_FAST_BENCHMARK _IOWR('g', 1, struct gup_benchmark)
18
+#define GUP_BENCHMARK _IOWR('g', 2, struct gup_benchmark)
19
+
20
+/* Similar to above, but use FOLL_PIN instead of FOLL_GET. */
21
+#define PIN_FAST_BENCHMARK _IOWR('g', 3, struct gup_benchmark)
22
+#define PIN_BENCHMARK _IOWR('g', 4, struct gup_benchmark)
23
+#define PIN_LONGTERM_BENCHMARK _IOWR('g', 5, struct gup_benchmark)
24
+
25
+/* Just the flags we need, copied from mm.h: */
26
+#define FOLL_WRITE 0x01 /* check pte is writable */
1827
1928 struct gup_benchmark {
20
- __u64 delta_usec;
29
+ __u64 get_delta_usec;
30
+ __u64 put_delta_usec;
2131 __u64 addr;
2232 __u64 size;
2333 __u32 nr_pages_per_call;
....@@ -29,11 +39,22 @@
2939 {
3040 struct gup_benchmark gup;
3141 unsigned long size = 128 * MB;
32
- int i, fd, opt, nr_pages = 1, thp = -1, repeats = 1, write = 0;
42
+ int i, fd, filed, opt, nr_pages = 1, thp = -1, repeats = 1, write = 0;
43
+ int cmd = GUP_FAST_BENCHMARK, flags = MAP_PRIVATE;
44
+ char *file = "/dev/zero";
3345 char *p;
3446
35
- while ((opt = getopt(argc, argv, "m:r:n:tT")) != -1) {
47
+ while ((opt = getopt(argc, argv, "m:r:n:f:abtTLUuwSH")) != -1) {
3648 switch (opt) {
49
+ case 'a':
50
+ cmd = PIN_FAST_BENCHMARK;
51
+ break;
52
+ case 'b':
53
+ cmd = PIN_BENCHMARK;
54
+ break;
55
+ case 'L':
56
+ cmd = PIN_LONGTERM_BENCHMARK;
57
+ break;
3758 case 'm':
3859 size = atoi(optarg) * MB;
3960 break;
....@@ -49,25 +70,51 @@
4970 case 'T':
5071 thp = 0;
5172 break;
73
+ case 'U':
74
+ cmd = GUP_BENCHMARK;
75
+ break;
76
+ case 'u':
77
+ cmd = GUP_FAST_BENCHMARK;
78
+ break;
5279 case 'w':
5380 write = 1;
81
+ break;
82
+ case 'f':
83
+ file = optarg;
84
+ break;
85
+ case 'S':
86
+ flags &= ~MAP_PRIVATE;
87
+ flags |= MAP_SHARED;
88
+ break;
89
+ case 'H':
90
+ flags |= (MAP_HUGETLB | MAP_ANONYMOUS);
5491 break;
5592 default:
5693 return -1;
5794 }
5895 }
5996
97
+ filed = open(file, O_RDWR|O_CREAT);
98
+ if (filed < 0) {
99
+ perror("open");
100
+ exit(filed);
101
+ }
102
+
60103 gup.nr_pages_per_call = nr_pages;
61
- gup.flags = write;
104
+ if (write)
105
+ gup.flags |= FOLL_WRITE;
62106
63107 fd = open("/sys/kernel/debug/gup_benchmark", O_RDWR);
64
- if (fd == -1)
65
- perror("open"), exit(1);
108
+ if (fd == -1) {
109
+ perror("open");
110
+ exit(1);
111
+ }
66112
67
- p = mmap(NULL, size, PROT_READ | PROT_WRITE,
68
- MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
69
- if (p == MAP_FAILED)
70
- perror("mmap"), exit(1);
113
+ p = mmap(NULL, size, PROT_READ | PROT_WRITE, flags, filed, 0);
114
+ if (p == MAP_FAILED) {
115
+ perror("mmap");
116
+ exit(1);
117
+ }
71118 gup.addr = (unsigned long)p;
72119
73120 if (thp == 1)
....@@ -80,10 +127,13 @@
80127
81128 for (i = 0; i < repeats; i++) {
82129 gup.size = size;
83
- if (ioctl(fd, GUP_FAST_BENCHMARK, &gup))
84
- perror("ioctl"), exit(1);
130
+ if (ioctl(fd, cmd, &gup)) {
131
+ perror("ioctl");
132
+ exit(1);
133
+ }
85134
86
- printf("Time: %lld us", gup.delta_usec);
135
+ printf("Time: get:%lld put:%lld us", gup.get_delta_usec,
136
+ gup.put_delta_usec);
87137 if (gup.size != size)
88138 printf(", truncated (size: %lld)", gup.size);
89139 printf("\n");