Mirror of strace – the linux syscall tracer
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

sched.c 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /*
  2. * Copyright (c) 2004 Ulrich Drepper <drepper@redhat.com>
  3. * Copyright (c) 2005 Roland McGrath <roland@redhat.com>
  4. * Copyright (c) 2012-2015 Dmitry V. Levin <ldv@altlinux.org>
  5. * Copyright (c) 2014-2018 The strace developers.
  6. * All rights reserved.
  7. *
  8. * SPDX-License-Identifier: LGPL-2.1-or-later
  9. */
  10. #include "defs.h"
  11. #include <sched.h>
  12. #include "sched_attr.h"
  13. #include "xlat/schedulers.h"
  14. #include "xlat/sched_flags.h"
  15. SYS_FUNC(sched_getscheduler)
  16. {
  17. if (entering(tcp)) {
  18. tprintf("%d", (int) tcp->u_arg[0]);
  19. } else if (!syserror(tcp)) {
  20. tcp->auxstr = xlookup(schedulers, (kernel_ulong_t) tcp->u_rval);
  21. return RVAL_STR;
  22. }
  23. return 0;
  24. }
  25. SYS_FUNC(sched_setscheduler)
  26. {
  27. tprintf("%d, ", (int) tcp->u_arg[0]);
  28. printxval(schedulers, tcp->u_arg[1], "SCHED_???");
  29. tprints(", ");
  30. printnum_int(tcp, tcp->u_arg[2], "%d");
  31. return RVAL_DECODED;
  32. }
  33. SYS_FUNC(sched_getparam)
  34. {
  35. if (entering(tcp))
  36. tprintf("%d, ", (int) tcp->u_arg[0]);
  37. else
  38. printnum_int(tcp, tcp->u_arg[1], "%d");
  39. return 0;
  40. }
  41. SYS_FUNC(sched_setparam)
  42. {
  43. tprintf("%d, ", (int) tcp->u_arg[0]);
  44. printnum_int(tcp, tcp->u_arg[1], "%d");
  45. return RVAL_DECODED;
  46. }
  47. SYS_FUNC(sched_get_priority_min)
  48. {
  49. printxval(schedulers, tcp->u_arg[0], "SCHED_???");
  50. return RVAL_DECODED;
  51. }
  52. SYS_FUNC(sched_rr_get_interval)
  53. {
  54. if (entering(tcp)) {
  55. tprintf("%d, ", (int) tcp->u_arg[0]);
  56. } else {
  57. if (syserror(tcp))
  58. printaddr(tcp->u_arg[1]);
  59. else
  60. print_timespec(tcp, tcp->u_arg[1]);
  61. }
  62. return 0;
  63. }
  64. static void
  65. print_sched_attr(struct tcb *const tcp, const kernel_ulong_t addr,
  66. unsigned int usize)
  67. {
  68. struct sched_attr attr = {};
  69. unsigned int size;
  70. if (usize) {
  71. /* called from sched_getattr */
  72. size = usize <= sizeof(attr) ? usize : (unsigned) sizeof(attr);
  73. if (umoven_or_printaddr(tcp, addr, size, &attr))
  74. return;
  75. /* the number of bytes written by the kernel */
  76. size = attr.size;
  77. } else {
  78. /* called from sched_setattr */
  79. if (umove_or_printaddr(tcp, addr, &attr.size))
  80. return;
  81. usize = attr.size;
  82. if (!usize)
  83. usize = SCHED_ATTR_MIN_SIZE;
  84. size = usize <= sizeof(attr) ? usize : (unsigned) sizeof(attr);
  85. if (size >= SCHED_ATTR_MIN_SIZE) {
  86. if (umoven_or_printaddr(tcp, addr, size, &attr))
  87. return;
  88. }
  89. }
  90. tprintf("{size=%u", attr.size);
  91. if (size >= SCHED_ATTR_MIN_SIZE) {
  92. tprints(", sched_policy=");
  93. printxval(schedulers, attr.sched_policy, "SCHED_???");
  94. tprints(", sched_flags=");
  95. printflags64(sched_flags, attr.sched_flags, "SCHED_FLAG_???");
  96. #define PRINT_SCHED_FIELD(field, fmt) \
  97. tprintf(", " #field "=%" fmt, attr.field)
  98. PRINT_SCHED_FIELD(sched_nice, "d");
  99. PRINT_SCHED_FIELD(sched_priority, "u");
  100. PRINT_SCHED_FIELD(sched_runtime, PRIu64);
  101. PRINT_SCHED_FIELD(sched_deadline, PRIu64);
  102. PRINT_SCHED_FIELD(sched_period, PRIu64);
  103. if (usize > size)
  104. tprints(", ...");
  105. }
  106. tprints("}");
  107. }
  108. SYS_FUNC(sched_setattr)
  109. {
  110. if (entering(tcp)) {
  111. tprintf("%d, ", (int) tcp->u_arg[0]);
  112. print_sched_attr(tcp, tcp->u_arg[1], 0);
  113. } else {
  114. struct sched_attr attr;
  115. if (verbose(tcp) && tcp->u_error == E2BIG
  116. && umove(tcp, tcp->u_arg[1], &attr.size) == 0) {
  117. tprintf(" => {size=%u}", attr.size);
  118. }
  119. tprintf(", %u", (unsigned int) tcp->u_arg[2]);
  120. }
  121. return 0;
  122. }
  123. SYS_FUNC(sched_getattr)
  124. {
  125. if (entering(tcp)) {
  126. tprintf("%d, ", (int) tcp->u_arg[0]);
  127. } else {
  128. const unsigned int size = tcp->u_arg[2];
  129. if (size)
  130. print_sched_attr(tcp, tcp->u_arg[1], size);
  131. else
  132. printaddr(tcp->u_arg[1]);
  133. tprints(", ");
  134. #ifdef AARCH64
  135. /*
  136. * Due to a subtle gcc bug that leads to miscompiled aarch64
  137. * kernels, the 3rd argument of sched_getattr is not quite 32-bit
  138. * as on other architectures. For more details see
  139. * https://lists.strace.io/pipermail/strace-devel/2017-March/006085.html
  140. */
  141. if (syserror(tcp))
  142. print_abnormal_hi(tcp->u_arg[2]);
  143. #endif
  144. tprintf("%u", size);
  145. tprintf(", %u", (unsigned int) tcp->u_arg[3]);
  146. }
  147. return 0;
  148. }