gup_benchmark.c 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. #include <fcntl.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <sys/ioctl.h>
  6. #include <sys/mman.h>
  7. #include <sys/prctl.h>
  8. #include <sys/stat.h>
  9. #include <sys/types.h>
  10. #include <linux/types.h>
  11. #define MB (1UL << 20)
  12. #define PAGE_SIZE sysconf(_SC_PAGESIZE)
  13. #define GUP_FAST_BENCHMARK _IOWR('g', 1, struct gup_benchmark)
  14. struct gup_benchmark {
  15. __u64 delta_usec;
  16. __u64 addr;
  17. __u64 size;
  18. __u32 nr_pages_per_call;
  19. __u32 flags;
  20. };
  21. int main(int argc, char **argv)
  22. {
  23. struct gup_benchmark gup;
  24. unsigned long size = 128 * MB;
  25. int i, fd, opt, nr_pages = 1, thp = -1, repeats = 1, write = 0;
  26. char *p;
  27. while ((opt = getopt(argc, argv, "m:r:n:tT")) != -1) {
  28. switch (opt) {
  29. case 'm':
  30. size = atoi(optarg) * MB;
  31. break;
  32. case 'r':
  33. repeats = atoi(optarg);
  34. break;
  35. case 'n':
  36. nr_pages = atoi(optarg);
  37. break;
  38. case 't':
  39. thp = 1;
  40. break;
  41. case 'T':
  42. thp = 0;
  43. break;
  44. case 'w':
  45. write = 1;
  46. default:
  47. return -1;
  48. }
  49. }
  50. gup.nr_pages_per_call = nr_pages;
  51. gup.flags = write;
  52. fd = open("/sys/kernel/debug/gup_benchmark", O_RDWR);
  53. if (fd == -1)
  54. perror("open"), exit(1);
  55. p = mmap(NULL, size, PROT_READ | PROT_WRITE,
  56. MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
  57. if (p == MAP_FAILED)
  58. perror("mmap"), exit(1);
  59. gup.addr = (unsigned long)p;
  60. if (thp == 1)
  61. madvise(p, size, MADV_HUGEPAGE);
  62. else if (thp == 0)
  63. madvise(p, size, MADV_NOHUGEPAGE);
  64. for (; (unsigned long)p < gup.addr + size; p += PAGE_SIZE)
  65. p[0] = 0;
  66. for (i = 0; i < repeats; i++) {
  67. gup.size = size;
  68. if (ioctl(fd, GUP_FAST_BENCHMARK, &gup))
  69. perror("ioctl"), exit(1);
  70. printf("Time: %lld us", gup.delta_usec);
  71. if (gup.size != size)
  72. printf(", truncated (size: %lld)", gup.size);
  73. printf("\n");
  74. }
  75. return 0;
  76. }