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 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  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-2019 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. static int
  53. do_sched_rr_get_interval(struct tcb *const tcp,
  54. const print_obj_by_addr_fn print_ts)
  55. {
  56. if (entering(tcp)) {
  57. tprintf("%d, ", (int) tcp->u_arg[0]);
  58. } else {
  59. if (syserror(tcp))
  60. printaddr(tcp->u_arg[1]);
  61. else
  62. print_ts(tcp, tcp->u_arg[1]);
  63. }
  64. return 0;
  65. }
  66. #if HAVE_ARCH_TIME32_SYSCALLS
  67. SYS_FUNC(sched_rr_get_interval_time32)
  68. {
  69. return do_sched_rr_get_interval(tcp, print_timespec32);
  70. }
  71. #endif
  72. SYS_FUNC(sched_rr_get_interval_time64)
  73. {
  74. return do_sched_rr_get_interval(tcp, print_timespec64);
  75. }
  76. static void
  77. print_sched_attr(struct tcb *const tcp, const kernel_ulong_t addr,
  78. unsigned int usize)
  79. {
  80. struct sched_attr attr = {};
  81. unsigned int size;
  82. if (usize) {
  83. /* called from sched_getattr */
  84. size = usize <= sizeof(attr) ? usize : (unsigned) sizeof(attr);
  85. if (umoven_or_printaddr(tcp, addr, size, &attr))
  86. return;
  87. /* the number of bytes written by the kernel */
  88. size = attr.size;
  89. } else {
  90. /* called from sched_setattr */
  91. if (umove_or_printaddr(tcp, addr, &attr.size))
  92. return;
  93. usize = attr.size;
  94. if (!usize)
  95. usize = SCHED_ATTR_MIN_SIZE;
  96. size = usize <= sizeof(attr) ? usize : (unsigned) sizeof(attr);
  97. if (size >= SCHED_ATTR_MIN_SIZE) {
  98. if (umoven_or_printaddr(tcp, addr, size, &attr))
  99. return;
  100. }
  101. }
  102. tprintf("{size=%u", attr.size);
  103. if (size >= SCHED_ATTR_MIN_SIZE) {
  104. tprints(", sched_policy=");
  105. printxval(schedulers, attr.sched_policy, "SCHED_???");
  106. tprints(", sched_flags=");
  107. printflags64(sched_flags, attr.sched_flags, "SCHED_FLAG_???");
  108. #define PRINT_SCHED_FIELD(field, fmt) \
  109. tprintf(", " #field "=%" fmt, attr.field)
  110. PRINT_SCHED_FIELD(sched_nice, "d");
  111. PRINT_SCHED_FIELD(sched_priority, "u");
  112. PRINT_SCHED_FIELD(sched_runtime, PRIu64);
  113. PRINT_SCHED_FIELD(sched_deadline, PRIu64);
  114. PRINT_SCHED_FIELD(sched_period, PRIu64);
  115. if (usize > size)
  116. tprints(", ...");
  117. }
  118. tprints("}");
  119. }
  120. SYS_FUNC(sched_setattr)
  121. {
  122. if (entering(tcp)) {
  123. tprintf("%d, ", (int) tcp->u_arg[0]);
  124. print_sched_attr(tcp, tcp->u_arg[1], 0);
  125. } else {
  126. struct sched_attr attr;
  127. if (verbose(tcp) && tcp->u_error == E2BIG
  128. && umove(tcp, tcp->u_arg[1], &attr.size) == 0) {
  129. tprintf(" => {size=%u}", attr.size);
  130. }
  131. tprintf(", %u", (unsigned int) tcp->u_arg[2]);
  132. }
  133. return 0;
  134. }
  135. SYS_FUNC(sched_getattr)
  136. {
  137. if (entering(tcp)) {
  138. tprintf("%d, ", (int) tcp->u_arg[0]);
  139. } else {
  140. const unsigned int size = tcp->u_arg[2];
  141. if (size)
  142. print_sched_attr(tcp, tcp->u_arg[1], size);
  143. else
  144. printaddr(tcp->u_arg[1]);
  145. tprints(", ");
  146. #ifdef AARCH64
  147. /*
  148. * Due to a subtle gcc bug that leads to miscompiled aarch64
  149. * kernels, the 3rd argument of sched_getattr is not quite 32-bit
  150. * as on other architectures. For more details see
  151. * https://lists.strace.io/pipermail/strace-devel/2017-March/006085.html
  152. */
  153. if (syserror(tcp))
  154. print_abnormal_hi(tcp->u_arg[2]);
  155. #endif
  156. tprintf("%u", size);
  157. tprintf(", %u", (unsigned int) tcp->u_arg[3]);
  158. }
  159. return 0;
  160. }