Branch data Line data Source code
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 : :
39 : 16 : SYS_FUNC(sched_getscheduler)
40 : : {
41 [ + + ]: 16 : if (entering(tcp)) {
42 : 8 : tprintf("%d", (int) tcp->u_arg[0]);
43 [ + + ]: 8 : } else if (!syserror(tcp)) {
44 : 4 : tcp->auxstr = xlookup(schedulers, (kernel_ulong_t) tcp->u_rval);
45 [ - + ]: 4 : if (tcp->auxstr != NULL)
46 : : return RVAL_STR;
47 : : }
48 : : return 0;
49 : : }
50 : :
51 : 20 : SYS_FUNC(sched_setscheduler)
52 : : {
53 : 20 : tprintf("%d, ", (int) tcp->u_arg[0]);
54 : 20 : printxval(schedulers, tcp->u_arg[1], "SCHED_???");
55 : 20 : tprints(", ");
56 : 20 : printnum_int(tcp, tcp->u_arg[2], "%d");
57 : :
58 : 20 : return RVAL_DECODED;
59 : : }
60 : :
61 : 8 : SYS_FUNC(sched_getparam)
62 : : {
63 [ + + ]: 8 : if (entering(tcp))
64 : 4 : tprintf("%d, ", (int) tcp->u_arg[0]);
65 : : else
66 : 4 : printnum_int(tcp, tcp->u_arg[1], "%d");
67 : 8 : return 0;
68 : : }
69 : :
70 : 4 : SYS_FUNC(sched_setparam)
71 : : {
72 : 4 : tprintf("%d, ", (int) tcp->u_arg[0]);
73 : 4 : printnum_int(tcp, tcp->u_arg[1], "%d");
74 : :
75 : 4 : return RVAL_DECODED;
76 : : }
77 : :
78 : 8 : SYS_FUNC(sched_get_priority_min)
79 : : {
80 : 8 : printxval(schedulers, tcp->u_arg[0], "SCHED_???");
81 : :
82 : 8 : return RVAL_DECODED;
83 : : }
84 : :
85 : 32 : SYS_FUNC(sched_rr_get_interval)
86 : : {
87 [ + + ]: 32 : if (entering(tcp)) {
88 : 16 : tprintf("%d, ", (int) tcp->u_arg[0]);
89 : : } else {
90 [ + + ]: 16 : if (syserror(tcp))
91 : 12 : printaddr(tcp->u_arg[1]);
92 : : else
93 : 4 : print_timespec(tcp, tcp->u_arg[1]);
94 : : }
95 : 32 : return 0;
96 : : }
97 : :
98 : : static void
99 : 48 : print_sched_attr(struct tcb *const tcp, const kernel_ulong_t addr,
100 : : unsigned int usize)
101 : : {
102 : 48 : struct sched_attr attr = {};
103 : : unsigned int size;
104 : :
105 [ + + ]: 48 : if (usize) {
106 : : /* called from sched_getattr */
107 : 16 : size = usize <= sizeof(attr) ? usize : (unsigned) sizeof(attr);
108 [ + + ]: 16 : if (umoven_or_printaddr(tcp, addr, size, &attr))
109 : 16 : return;
110 : : /* the number of bytes written by the kernel */
111 : 8 : size = attr.size;
112 : : } else {
113 : : /* called from sched_setattr */
114 [ + + ]: 32 : if (umove_or_printaddr(tcp, addr, &attr.size))
115 : : return;
116 : 28 : usize = attr.size;
117 [ + + ]: 28 : if (!usize)
118 : 4 : usize = SCHED_ATTR_MIN_SIZE;
119 : 28 : size = usize <= sizeof(attr) ? usize : (unsigned) sizeof(attr);
120 [ + + ]: 28 : if (size >= SCHED_ATTR_MIN_SIZE) {
121 [ + + ]: 20 : if (umoven_or_printaddr(tcp, addr, size, &attr))
122 : : return;
123 : : }
124 : : }
125 : :
126 : 32 : tprintf("{size=%u", attr.size);
127 : :
128 [ + + ]: 32 : if (size >= SCHED_ATTR_MIN_SIZE) {
129 : 24 : tprints(", sched_policy=");
130 : 24 : printxval(schedulers, attr.sched_policy, "SCHED_???");
131 : 24 : tprints(", sched_flags=");
132 : 24 : printflags64(sched_flags, attr.sched_flags, "SCHED_FLAG_???");
133 : :
134 : : #define PRINT_SCHED_FIELD(field, fmt) \
135 : : tprintf(", " #field "=%" fmt, attr.field)
136 : :
137 : 24 : PRINT_SCHED_FIELD(sched_nice, "d");
138 : 24 : PRINT_SCHED_FIELD(sched_priority, "u");
139 : 24 : PRINT_SCHED_FIELD(sched_runtime, PRIu64);
140 : 24 : PRINT_SCHED_FIELD(sched_deadline, PRIu64);
141 : 24 : PRINT_SCHED_FIELD(sched_period, PRIu64);
142 : :
143 [ + + ]: 24 : if (usize > size)
144 : 4 : tprints(", ...");
145 : : }
146 : :
147 : 32 : tprints("}");
148 : : }
149 : :
150 : 64 : SYS_FUNC(sched_setattr)
151 : : {
152 [ + + ]: 64 : if (entering(tcp)) {
153 : 32 : tprintf("%d, ", (int) tcp->u_arg[0]);
154 : 32 : print_sched_attr(tcp, tcp->u_arg[1], 0);
155 : : } else {
156 : : struct sched_attr attr;
157 : :
158 [ + - ][ + + ]: 32 : if (verbose(tcp) && tcp->u_error == E2BIG
159 [ + - ]: 8 : && umove(tcp, tcp->u_arg[1], &attr.size) == 0) {
160 : 8 : tprintf(" => {size=%u}", attr.size);
161 : : }
162 : :
163 : 32 : tprintf(", %u", (unsigned int) tcp->u_arg[2]);
164 : : }
165 : :
166 : 64 : return 0;
167 : : }
168 : :
169 : 56 : SYS_FUNC(sched_getattr)
170 : : {
171 [ + + ]: 56 : if (entering(tcp)) {
172 : 28 : tprintf("%d, ", (int) tcp->u_arg[0]);
173 : : } else {
174 : 28 : const unsigned int size = tcp->u_arg[2];
175 : :
176 [ + + ]: 28 : if (size)
177 : 16 : print_sched_attr(tcp, tcp->u_arg[1], size);
178 : : else
179 : 12 : printaddr(tcp->u_arg[1]);
180 : 28 : 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 : 28 : tprintf("%u", size);
192 : 28 : tprintf(", %u", (unsigned int) tcp->u_arg[3]);
193 : : }
194 : :
195 : 56 : return 0;
196 : : }
|