tm-syscall.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /*
  2. * Copyright 2015, Sam Bobroff, IBM Corp.
  3. * Licensed under GPLv2.
  4. *
  5. * Test the kernel's system call code to ensure that a system call
  6. * made from within an active HTM transaction is aborted with the
  7. * correct failure code.
  8. * Conversely, ensure that a system call made from within a
  9. * suspended transaction can succeed.
  10. */
  11. #include <stdio.h>
  12. #include <unistd.h>
  13. #include <sys/syscall.h>
  14. #include <asm/tm.h>
  15. #include <sys/time.h>
  16. #include <stdlib.h>
  17. #include "utils.h"
  18. #include "tm.h"
  19. extern int getppid_tm_active(void);
  20. extern int getppid_tm_suspended(void);
  21. unsigned retries = 0;
  22. #define TEST_DURATION 10 /* seconds */
  23. #define TM_RETRIES 100
  24. pid_t getppid_tm(bool suspend)
  25. {
  26. int i;
  27. pid_t pid;
  28. for (i = 0; i < TM_RETRIES; i++) {
  29. if (suspend)
  30. pid = getppid_tm_suspended();
  31. else
  32. pid = getppid_tm_active();
  33. if (pid >= 0)
  34. return pid;
  35. if (failure_is_persistent()) {
  36. if (failure_is_syscall())
  37. return -1;
  38. printf("Unexpected persistent transaction failure.\n");
  39. printf("TEXASR 0x%016lx, TFIAR 0x%016lx.\n",
  40. __builtin_get_texasr(), __builtin_get_tfiar());
  41. exit(-1);
  42. }
  43. retries++;
  44. }
  45. printf("Exceeded limit of %d temporary transaction failures.\n", TM_RETRIES);
  46. printf("TEXASR 0x%016lx, TFIAR 0x%016lx.\n",
  47. __builtin_get_texasr(), __builtin_get_tfiar());
  48. exit(-1);
  49. }
  50. int tm_syscall(void)
  51. {
  52. unsigned count = 0;
  53. struct timeval end, now;
  54. SKIP_IF(!have_htm_nosc());
  55. setbuf(stdout, NULL);
  56. printf("Testing transactional syscalls for %d seconds...\n", TEST_DURATION);
  57. gettimeofday(&end, NULL);
  58. now.tv_sec = TEST_DURATION;
  59. now.tv_usec = 0;
  60. timeradd(&end, &now, &end);
  61. for (count = 0; timercmp(&now, &end, <); count++) {
  62. /*
  63. * Test a syscall within a suspended transaction and verify
  64. * that it succeeds.
  65. */
  66. FAIL_IF(getppid_tm(true) == -1); /* Should succeed. */
  67. /*
  68. * Test a syscall within an active transaction and verify that
  69. * it fails with the correct failure code.
  70. */
  71. FAIL_IF(getppid_tm(false) != -1); /* Should fail... */
  72. FAIL_IF(!failure_is_persistent()); /* ...persistently... */
  73. FAIL_IF(!failure_is_syscall()); /* ...with code syscall. */
  74. gettimeofday(&now, 0);
  75. }
  76. printf("%d active and suspended transactions behaved correctly.\n", count);
  77. printf("(There were %d transaction retries.)\n", retries);
  78. return 0;
  79. }
  80. int main(void)
  81. {
  82. return test_harness(tm_syscall, "tm_syscall");
  83. }