Home | History | Annotate | Download | only in strace
      1 /*
      2  * Copyright (c) 2004 Ulrich Drepper <drepper (at) redhat.com>
      3  * Copyright (c) 2005 Roland McGrath <roland (at) redhat.com>
      4  * Copyright (c) 2012-2015 Dmitry V. Levin <ldv (at) altlinux.org>
      5  * Copyright (c) 2014-2018 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 
     39 SYS_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 		return RVAL_STR;
     46 	}
     47 	return 0;
     48 }
     49 
     50 SYS_FUNC(sched_setscheduler)
     51 {
     52 	tprintf("%d, ", (int) tcp->u_arg[0]);
     53 	printxval(schedulers, tcp->u_arg[1], "SCHED_???");
     54 	tprints(", ");
     55 	printnum_int(tcp, tcp->u_arg[2], "%d");
     56 
     57 	return RVAL_DECODED;
     58 }
     59 
     60 SYS_FUNC(sched_getparam)
     61 {
     62 	if (entering(tcp))
     63 		tprintf("%d, ", (int) tcp->u_arg[0]);
     64 	else
     65 		printnum_int(tcp, tcp->u_arg[1], "%d");
     66 	return 0;
     67 }
     68 
     69 SYS_FUNC(sched_setparam)
     70 {
     71 	tprintf("%d, ", (int) tcp->u_arg[0]);
     72 	printnum_int(tcp, tcp->u_arg[1], "%d");
     73 
     74 	return RVAL_DECODED;
     75 }
     76 
     77 SYS_FUNC(sched_get_priority_min)
     78 {
     79 	printxval(schedulers, tcp->u_arg[0], "SCHED_???");
     80 
     81 	return RVAL_DECODED;
     82 }
     83 
     84 SYS_FUNC(sched_rr_get_interval)
     85 {
     86 	if (entering(tcp)) {
     87 		tprintf("%d, ", (int) tcp->u_arg[0]);
     88 	} else {
     89 		if (syserror(tcp))
     90 			printaddr(tcp->u_arg[1]);
     91 		else
     92 			print_timespec(tcp, tcp->u_arg[1]);
     93 	}
     94 	return 0;
     95 }
     96 
     97 static void
     98 print_sched_attr(struct tcb *const tcp, const kernel_ulong_t addr,
     99 		 unsigned int usize)
    100 {
    101 	struct sched_attr attr = {};
    102 	unsigned int size;
    103 
    104 	if (usize) {
    105 		/* called from sched_getattr */
    106 		size = usize <= sizeof(attr) ? usize : (unsigned) sizeof(attr);
    107 		if (umoven_or_printaddr(tcp, addr, size, &attr))
    108 			return;
    109 		/* the number of bytes written by the kernel */
    110 		size = attr.size;
    111 	} else {
    112 		/* called from sched_setattr */
    113 		if (umove_or_printaddr(tcp, addr, &attr.size))
    114 			return;
    115 		usize = attr.size;
    116 		if (!usize)
    117 			usize = SCHED_ATTR_MIN_SIZE;
    118 		size = usize <= sizeof(attr) ? usize : (unsigned) sizeof(attr);
    119 		if (size >= SCHED_ATTR_MIN_SIZE) {
    120 			if (umoven_or_printaddr(tcp, addr, size, &attr))
    121 				return;
    122 		}
    123 	}
    124 
    125 	tprintf("{size=%u", attr.size);
    126 
    127 	if (size >= SCHED_ATTR_MIN_SIZE) {
    128 		tprints(", sched_policy=");
    129 		printxval(schedulers, attr.sched_policy, "SCHED_???");
    130 		tprints(", sched_flags=");
    131 		printflags64(sched_flags, attr.sched_flags, "SCHED_FLAG_???");
    132 
    133 #define PRINT_SCHED_FIELD(field, fmt)			\
    134 		tprintf(", " #field "=%" fmt, attr.field)
    135 
    136 		PRINT_SCHED_FIELD(sched_nice, "d");
    137 		PRINT_SCHED_FIELD(sched_priority, "u");
    138 		PRINT_SCHED_FIELD(sched_runtime, PRIu64);
    139 		PRINT_SCHED_FIELD(sched_deadline, PRIu64);
    140 		PRINT_SCHED_FIELD(sched_period, PRIu64);
    141 
    142 		if (usize > size)
    143 			tprints(", ...");
    144 	}
    145 
    146 	tprints("}");
    147 }
    148 
    149 SYS_FUNC(sched_setattr)
    150 {
    151 	if (entering(tcp)) {
    152 		tprintf("%d, ", (int) tcp->u_arg[0]);
    153 		print_sched_attr(tcp, tcp->u_arg[1], 0);
    154 	} else {
    155 		struct sched_attr attr;
    156 
    157 		if (verbose(tcp) && tcp->u_error == E2BIG
    158 		    && umove(tcp, tcp->u_arg[1], &attr.size) == 0) {
    159 			tprintf(" => {size=%u}", attr.size);
    160 		}
    161 
    162 		tprintf(", %u", (unsigned int) tcp->u_arg[2]);
    163 	}
    164 
    165 	return 0;
    166 }
    167 
    168 SYS_FUNC(sched_getattr)
    169 {
    170 	if (entering(tcp)) {
    171 		tprintf("%d, ", (int) tcp->u_arg[0]);
    172 	} else {
    173 		const unsigned int size = tcp->u_arg[2];
    174 
    175 		if (size)
    176 			print_sched_attr(tcp, tcp->u_arg[1], size);
    177 		else
    178 			printaddr(tcp->u_arg[1]);
    179 		tprints(", ");
    180 #ifdef AARCH64
    181 		/*
    182 		 * Due to a subtle gcc bug that leads to miscompiled aarch64
    183 		 * kernels, the 3rd argument of sched_getattr is not quite 32-bit
    184 		 * as on other architectures.  For more details see
    185 		 * https://lists.strace.io/pipermail/strace-devel/2017-March/006085.html
    186 		 */
    187 		if (syserror(tcp))
    188 			print_abnormal_hi(tcp->u_arg[2]);
    189 #endif
    190 		tprintf("%u", size);
    191 		tprintf(", %u", (unsigned int) tcp->u_arg[3]);
    192 	}
    193 
    194 	return 0;
    195 }
    196