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