]> granicus.if.org Git - strace/blob - sched.c
mmap_cache: add function to enable mmap_cache
[strace] / sched.c
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 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                 if (tcp->auxstr != NULL)
46                         return RVAL_STR;
47         }
48         return 0;
49 }
50
51 SYS_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
61 SYS_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
70 SYS_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
78 SYS_FUNC(sched_get_priority_min)
79 {
80         printxval(schedulers, tcp->u_arg[0], "SCHED_???");
81
82         return RVAL_DECODED;
83 }
84
85 SYS_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
98 static void
99 print_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
150 SYS_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
169 SYS_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://lists.strace.io/pipermail/strace-devel/2017-March/006085.html
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 }