gup_benchmark.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  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. __u64 expansion[10]; /* For future use */
  21. };
  22. int main(int argc, char **argv)
  23. {
  24. struct gup_benchmark gup;
  25. unsigned long size = 128 * MB;
  26. int i, fd, opt, nr_pages = 1, thp = -1, repeats = 1, write = 0;
  27. char *p;
  28. while ((opt = getopt(argc, argv, "m:r:n:tT")) != -1) {
  29. switch (opt) {
  30. case 'm':
  31. size = atoi(optarg) * MB;
  32. break;
  33. case 'r':
  34. repeats = atoi(optarg);
  35. break;
  36. case 'n':
  37. nr_pages = atoi(optarg);
  38. break;
  39. case 't':
  40. thp = 1;
  41. break;
  42. case 'T':
  43. thp = 0;
  44. break;
  45. case 'w':
  46. write = 1;
  47. break;
  48. default:
  49. return -1;
  50. }
  51. }
  52. gup.nr_pages_per_call = nr_pages;
  53. gup.flags = write;
  54. fd = open("/sys/kernel/debug/gup_benchmark", O_RDWR);
  55. if (fd == -1)
  56. perror("open"), exit(1);
  57. p = mmap(NULL, size, PROT_READ | PROT_WRITE,
  58. MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
  59. if (p == MAP_FAILED)
  60. perror("mmap"), exit(1);
  61. gup.addr = (unsigned long)p;
  62. if (thp == 1)
  63. madvise(p, size, MADV_HUGEPAGE);
  64. else if (thp == 0)
  65. madvise(p, size, MADV_NOHUGEPAGE);
  66. for (; (unsigned long)p < gup.addr + size; p += PAGE_SIZE)
  67. p[0] = 0;
  68. for (i = 0; i < repeats; i++) {
  69. gup.size = size;
  70. if (ioctl(fd, GUP_FAST_BENCHMARK, &gup))
  71. perror("ioctl"), exit(1);
  72. printf("Time: %lld us", gup.delta_usec);
  73. if (gup.size != size)
  74. printf(", truncated (size: %lld)", gup.size);
  75. printf("\n");
  76. }
  77. return 0;
  78. }