]> granicus.if.org Git - strace/blob - numa.c
ececff92f64fba93350ccefe7f9607581a7fab6b
[strace] / numa.c
1 /*
2  * Copyright (c) 2003-2007 Ulrich Drepper <drepper@redhat.com>
3  * Copyright (c) 2005-2016 Dmitry V. Levin <ldv@altlinux.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "defs.h"
30
31 static bool
32 print_node(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
33 {
34         if (elem_size < sizeof(kernel_ulong_t)) {
35                 tprintf("%#0*x", (int) elem_size * 2 + 2,
36                         * (unsigned int *) elem_buf);
37         } else {
38                 tprintf("%#0*" PRI_krx, (int) elem_size * 2 + 2,
39                         * (kernel_ulong_t *) elem_buf);
40         }
41
42         return true;
43 }
44
45 static void
46 print_nodemask(struct tcb *const tcp, const kernel_ulong_t addr,
47                const kernel_ulong_t maxnodes)
48 {
49         const unsigned int bits_per_long = 8 * current_wordsize;
50         const kernel_ulong_t nmemb =
51                 (maxnodes + bits_per_long - 2) / bits_per_long;
52
53         if (nmemb < maxnodes / bits_per_long ||
54             (maxnodes && !nmemb)) {
55                 printaddr(addr);
56                 return;
57         }
58
59         kernel_ulong_t buf;
60         print_array(tcp, addr, nmemb, &buf, current_wordsize,
61                     umoven_or_printaddr, print_node, 0);
62 }
63
64 SYS_FUNC(migrate_pages)
65 {
66         tprintf("%d, %" PRI_kru ", ", (int) tcp->u_arg[0], tcp->u_arg[1]);
67         print_nodemask(tcp, tcp->u_arg[2], tcp->u_arg[1]);
68         tprints(", ");
69         print_nodemask(tcp, tcp->u_arg[3], tcp->u_arg[1]);
70
71         return RVAL_DECODED;
72 }
73
74 #include "xlat/policies.h"
75 #include "xlat/mbindflags.h"
76
77 SYS_FUNC(mbind)
78 {
79         printaddr(tcp->u_arg[0]);
80         tprintf(", %" PRI_kru ", ", tcp->u_arg[1]);
81         printxval64(policies, tcp->u_arg[2], "MPOL_???");
82         tprints(", ");
83         print_nodemask(tcp, tcp->u_arg[3], tcp->u_arg[4]);
84         tprintf(", %" PRI_kru ", ", tcp->u_arg[4]);
85         printflags(mbindflags, tcp->u_arg[5], "MPOL_???");
86
87         return RVAL_DECODED;
88 }
89
90 SYS_FUNC(set_mempolicy)
91 {
92         printxval(policies, tcp->u_arg[0], "MPOL_???");
93         tprints(", ");
94         print_nodemask(tcp, tcp->u_arg[1], tcp->u_arg[2]);
95         tprintf(", %" PRI_kru, tcp->u_arg[2]);
96
97         return RVAL_DECODED;
98 }
99
100 #include "xlat/mempolicyflags.h"
101
102 SYS_FUNC(get_mempolicy)
103 {
104         if (exiting(tcp)) {
105                 int pol;
106                 if (!umove_or_printaddr(tcp, tcp->u_arg[0], &pol)) {
107                         tprints("[");
108                         printxval(policies, pol, "MPOL_???");
109                         tprints("]");
110                 }
111                 tprints(", ");
112                 print_nodemask(tcp, tcp->u_arg[1], tcp->u_arg[2]);
113                 tprintf(", %" PRI_kru ", ", tcp->u_arg[2]);
114                 printaddr(tcp->u_arg[3]);
115                 tprints(", ");
116                 printflags64(mempolicyflags, tcp->u_arg[4], "MPOL_???");
117         }
118         return 0;
119 }
120
121 #include "xlat/move_pages_flags.h"
122
123 static bool
124 print_addr(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
125 {
126         kernel_ulong_t addr;
127
128         if (elem_size < sizeof(addr)) {
129                 addr = * (unsigned int *) elem_buf;
130         } else {
131                 addr = * (kernel_ulong_t *) elem_buf;
132         }
133
134         printaddr(addr);
135
136         return true;
137 }
138
139 static bool
140 print_status(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
141 {
142         const int status = * (int *) elem_buf;
143
144         if (status < 0 && (unsigned) -status < nerrnos)
145                 tprintf("%s", errnoent[-status]);
146         else
147                 tprintf("%d", status);
148
149         return true;
150 }
151
152 static bool
153 print_int(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
154 {
155         tprintf("%d", * (int *) elem_buf);
156
157         return true;
158 }
159
160 SYS_FUNC(move_pages)
161 {
162         const kernel_ulong_t npages = tcp->u_arg[1];
163         kernel_ulong_t buf;
164
165         if (entering(tcp)) {
166                 tprintf("%d, %" PRI_kru ", ", (int) tcp->u_arg[0], npages);
167                 print_array(tcp, tcp->u_arg[2], npages, &buf, current_wordsize,
168                             umoven_or_printaddr, print_addr, 0);
169                 tprints(", ");
170                 print_array(tcp, tcp->u_arg[3], npages, &buf, sizeof(int),
171                             umoven_or_printaddr, print_int, 0);
172                 tprints(", ");
173         } else {
174                 print_array(tcp, tcp->u_arg[4], npages, &buf, sizeof(int),
175                             umoven_or_printaddr, print_status, 0);
176                 tprints(", ");
177                 printflags(move_pages_flags, tcp->u_arg[5], "MPOL_???");
178         }
179         return 0;
180 }