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-2017 The strace developers. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include "defs.h" 32 33#include <sched.h> 34#include "sched_attr.h" 35 36#include "xlat/schedulers.h" 37#include "xlat/sched_flags.h" 38 39SYS_FUNC(sched_getscheduler) 40{ 41 if (entering(tcp)) { 42 tprintf("%d", (int) tcp->u_arg[0]); 43 } else if (!syserror(tcp)) { 44 tcp->auxstr = xlookup(schedulers, (kernel_ulong_t) tcp->u_rval); 45 if (tcp->auxstr != NULL) 46 return RVAL_STR; 47 } 48 return 0; 49} 50 51SYS_FUNC(sched_setscheduler) 52{ 53 tprintf("%d, ", (int) tcp->u_arg[0]); 54 printxval(schedulers, tcp->u_arg[1], "SCHED_???"); 55 tprints(", "); 56 printnum_int(tcp, tcp->u_arg[2], "%d"); 57 58 return RVAL_DECODED; 59} 60 61SYS_FUNC(sched_getparam) 62{ 63 if (entering(tcp)) 64 tprintf("%d, ", (int) tcp->u_arg[0]); 65 else 66 printnum_int(tcp, tcp->u_arg[1], "%d"); 67 return 0; 68} 69 70SYS_FUNC(sched_setparam) 71{ 72 tprintf("%d, ", (int) tcp->u_arg[0]); 73 printnum_int(tcp, tcp->u_arg[1], "%d"); 74 75 return RVAL_DECODED; 76} 77 78SYS_FUNC(sched_get_priority_min) 79{ 80 printxval(schedulers, tcp->u_arg[0], "SCHED_???"); 81 82 return RVAL_DECODED; 83} 84 85SYS_FUNC(sched_rr_get_interval) 86{ 87 if (entering(tcp)) { 88 tprintf("%d, ", (int) tcp->u_arg[0]); 89 } else { 90 if (syserror(tcp)) 91 printaddr(tcp->u_arg[1]); 92 else 93 print_timespec(tcp, tcp->u_arg[1]); 94 } 95 return 0; 96} 97 98static void 99print_sched_attr(struct tcb *const tcp, const kernel_ulong_t addr, 100 unsigned int usize) 101{ 102 struct sched_attr attr = {}; 103 unsigned int size; 104 105 if (usize) { 106 /* called from sched_getattr */ 107 size = usize <= sizeof(attr) ? usize : (unsigned) sizeof(attr); 108 if (umoven_or_printaddr(tcp, addr, size, &attr)) 109 return; 110 /* the number of bytes written by the kernel */ 111 size = attr.size; 112 } else { 113 /* called from sched_setattr */ 114 if (umove_or_printaddr(tcp, addr, &attr.size)) 115 return; 116 usize = attr.size; 117 if (!usize) 118 usize = SCHED_ATTR_MIN_SIZE; 119 size = usize <= sizeof(attr) ? usize : (unsigned) sizeof(attr); 120 if (size >= SCHED_ATTR_MIN_SIZE) { 121 if (umoven_or_printaddr(tcp, addr, size, &attr)) 122 return; 123 } 124 } 125 126 tprintf("{size=%u", attr.size); 127 128 if (size >= SCHED_ATTR_MIN_SIZE) { 129 tprints(", sched_policy="); 130 printxval(schedulers, attr.sched_policy, "SCHED_???"); 131 tprints(", sched_flags="); 132 printflags64(sched_flags, attr.sched_flags, "SCHED_FLAG_???"); 133 134#define PRINT_SCHED_FIELD(field, fmt) \ 135 tprintf(", " #field "=%" fmt, attr.field) 136 137 PRINT_SCHED_FIELD(sched_nice, "d"); 138 PRINT_SCHED_FIELD(sched_priority, "u"); 139 PRINT_SCHED_FIELD(sched_runtime, PRIu64); 140 PRINT_SCHED_FIELD(sched_deadline, PRIu64); 141 PRINT_SCHED_FIELD(sched_period, PRIu64); 142 143 if (usize > size) 144 tprints(", ..."); 145 } 146 147 tprints("}"); 148} 149 150SYS_FUNC(sched_setattr) 151{ 152 if (entering(tcp)) { 153 tprintf("%d, ", (int) tcp->u_arg[0]); 154 print_sched_attr(tcp, tcp->u_arg[1], 0); 155 } else { 156 struct sched_attr attr; 157 158 if (verbose(tcp) && tcp->u_error == E2BIG 159 && umove(tcp, tcp->u_arg[1], &attr.size) == 0) { 160 tprintf(" => {size=%u}", attr.size); 161 } 162 163 tprintf(", %u", (unsigned int) tcp->u_arg[2]); 164 } 165 166 return 0; 167} 168 169SYS_FUNC(sched_getattr) 170{ 171 if (entering(tcp)) { 172 tprintf("%d, ", (int) tcp->u_arg[0]); 173 } else { 174 const unsigned int size = tcp->u_arg[2]; 175 176 if (size) 177 print_sched_attr(tcp, tcp->u_arg[1], size); 178 else 179 printaddr(tcp->u_arg[1]); 180 tprints(", "); 181#ifdef AARCH64 182 /* 183 * Due to a subtle gcc bug that leads to miscompiled aarch64 184 * kernels, the 3rd argument of sched_getattr is not quite 32-bit 185 * as on other architectures. For more details see 186 * https://sourceforge.net/p/strace/mailman/message/35721703/ 187 */ 188 if (syserror(tcp)) 189 print_abnormal_hi(tcp->u_arg[2]); 190#endif 191 tprintf("%u", size); 192 tprintf(", %u", (unsigned int) tcp->u_arg[3]); 193 } 194 195 return 0; 196} 197