1 /*
2  * numa_conf.h
3  *
4  * Copyright (C) 2014-2015 Red Hat, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library.  If not, see
18  * <http://www.gnu.org/licenses/>.
19  */
20 
21 #pragma once
22 
23 #include <libxml/xpath.h>
24 
25 #include "internal.h"
26 #include "virbitmap.h"
27 #include "virbuffer.h"
28 #include "virenum.h"
29 
30 
31 typedef struct _virDomainNuma virDomainNuma;
32 
33 typedef enum {
34     VIR_DOMAIN_NUMATUNE_PLACEMENT_DEFAULT = 0,
35     VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC,
36     VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO,
37 
38     VIR_DOMAIN_NUMATUNE_PLACEMENT_LAST
39 } virDomainNumatunePlacement;
40 
41 VIR_ENUM_DECL(virDomainNumatunePlacement);
42 VIR_ENUM_DECL(virDomainNumatuneMemMode);
43 
44 typedef enum {
45     VIR_DOMAIN_MEMORY_ACCESS_DEFAULT = 0,  /*  No memory access defined */
46     VIR_DOMAIN_MEMORY_ACCESS_SHARED,    /* Memory access is set as shared */
47     VIR_DOMAIN_MEMORY_ACCESS_PRIVATE,   /* Memory access is set as private */
48 
49     VIR_DOMAIN_MEMORY_ACCESS_LAST,
50 } virDomainMemoryAccess;
51 VIR_ENUM_DECL(virDomainMemoryAccess);
52 
53 typedef enum {
54     VIR_NUMA_CACHE_ASSOCIATIVITY_NONE,    /* No associativity */
55     VIR_NUMA_CACHE_ASSOCIATIVITY_DIRECT,  /* Direct mapped cache */
56     VIR_NUMA_CACHE_ASSOCIATIVITY_FULL,    /* Fully associative cache */
57 
58     VIR_NUMA_CACHE_ASSOCIATIVITY_LAST
59 } virNumaCacheAssociativity;
60 VIR_ENUM_DECL(virNumaCacheAssociativity);
61 
62 typedef enum {
63     VIR_NUMA_CACHE_POLICY_NONE,           /* No policy */
64     VIR_NUMA_CACHE_POLICY_WRITEBACK,      /* Write-back policy */
65     VIR_NUMA_CACHE_POLICY_WRITETHROUGH,   /* Write-through policy */
66 
67     VIR_NUMA_CACHE_POLICY_LAST
68 } virNumaCachePolicy;
69 VIR_ENUM_DECL(virNumaCachePolicy);
70 
71 typedef enum {
72     VIR_NUMA_INTERCONNECT_TYPE_LATENCY,
73     VIR_NUMA_INTERCONNECT_TYPE_BANDWIDTH,
74 } virNumaInterconnectType;
75 
76 typedef enum {
77     VIR_MEMORY_LATENCY_NONE = 0, /* No memory latency defined */
78     VIR_MEMORY_LATENCY_ACCESS,   /* Access latency */
79     VIR_MEMORY_LATENCY_READ,     /* Read latency */
80     VIR_MEMORY_LATENCY_WRITE,    /* Write latency */
81 
82     VIR_MEMORY_LATENCY_LAST
83 } virMemoryLatency;
84 VIR_ENUM_DECL(virMemoryLatency);
85 
86 
87 virDomainNuma *virDomainNumaNew(void);
88 void virDomainNumaFree(virDomainNuma *numa);
89 
90 /*
91  * XML Parse/Format functions
92  */
93 int virDomainNumatuneParseXML(virDomainNuma *numa,
94                               bool placement_static,
95                               xmlXPathContextPtr ctxt)
96     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3);
97 
98 int virDomainNumatuneFormatXML(virBuffer *buf, virDomainNuma *numatune)
99     ATTRIBUTE_NONNULL(1);
100 
101 /*
102  * Getters
103  */
104 int virDomainNumatuneGetMode(virDomainNuma *numatune,
105                              int cellid,
106                              virDomainNumatuneMemMode *mode);
107 
108 virBitmap *virDomainNumatuneGetNodeset(virDomainNuma *numatune,
109                                          virBitmap *auto_nodeset,
110                                          int cellid);
111 
112 int virDomainNumatuneMaybeGetNodeset(virDomainNuma *numatune,
113                                      virBitmap *auto_nodeset,
114                                      virBitmap **retNodeset,
115                                      int cellid);
116 
117 size_t virDomainNumaGetNodeCount(virDomainNuma *numa);
118 
119 bool virDomainNumaNodeDistanceIsUsingDefaults(virDomainNuma *numa,
120                                               size_t node,
121                                               size_t sibling)
122     ATTRIBUTE_NONNULL(1);
123 bool virDomainNumaNodesDistancesAreBeingSet(virDomainNuma *numa)
124     ATTRIBUTE_NONNULL(1);
125 size_t virDomainNumaGetNodeDistance(virDomainNuma *numa,
126                                     size_t node,
127                                     size_t sibling)
128     ATTRIBUTE_NONNULL(1);
129 
130 virBitmap *virDomainNumaGetNodeCpumask(virDomainNuma *numa,
131                                          size_t node)
132     ATTRIBUTE_NONNULL(1);
133 virDomainMemoryAccess virDomainNumaGetNodeMemoryAccessMode(virDomainNuma *numa,
134                                                       size_t node)
135     ATTRIBUTE_NONNULL(1);
136 virTristateBool virDomainNumaGetNodeDiscard(virDomainNuma *numa,
137                                             size_t node)
138     ATTRIBUTE_NONNULL(1);
139 unsigned long long virDomainNumaGetNodeMemorySize(virDomainNuma *numa,
140                                                   size_t node)
141     ATTRIBUTE_NONNULL(1);
142 unsigned long long virDomainNumaGetMemorySize(virDomainNuma *numa)
143     ATTRIBUTE_NONNULL(1);
144 
145 unsigned int
146 virDomainNumaGetMaxCPUID(virDomainNuma *numa);
147 
148 /*
149  * Formatters
150  */
151 char *virDomainNumatuneFormatNodeset(virDomainNuma *numatune,
152                                      virBitmap *auto_nodeset,
153                                      int cellid);
154 
155 int virDomainNumatuneMaybeFormatNodeset(virDomainNuma *numatune,
156                                         virBitmap *auto_nodeset,
157                                         char **mask,
158                                         int cellid);
159 
160 /*
161  * Setters
162  */
163 int virDomainNumatuneSet(virDomainNuma *numa,
164                          bool placement_static,
165                          int placement,
166                          int mode,
167                          virBitmap *nodeset)
168     ATTRIBUTE_NONNULL(1);
169 
170 size_t virDomainNumaSetNodeCount(virDomainNuma *numa,
171                                  size_t nmem_nodes)
172     ATTRIBUTE_NONNULL(1);
173 
174 void virDomainNumaSetNodeMemorySize(virDomainNuma *numa,
175                                     size_t node,
176                                     unsigned long long size)
177     ATTRIBUTE_NONNULL(1);
178 
179 int virDomainNumaSetNodeDistance(virDomainNuma *numa,
180                                  size_t node,
181                                  size_t sibling,
182                                  unsigned int value)
183     ATTRIBUTE_NONNULL(1);
184 
185 size_t virDomainNumaSetNodeDistanceCount(virDomainNuma *numa,
186                                          size_t node,
187                                          size_t ndistances)
188     ATTRIBUTE_NONNULL(1);
189 
190 void  virDomainNumaSetNodeCpumask(virDomainNuma *numa,
191                                   size_t node,
192                                   virBitmap *cpumask)
193     ATTRIBUTE_NONNULL(1);
194 
195 /*
196  * Other accessors
197  */
198 bool virDomainNumaEquals(virDomainNuma *n1,
199                          virDomainNuma *n2);
200 
201 bool virDomainNumaCheckABIStability(virDomainNuma *src,
202                                     virDomainNuma *tgt);
203 
204 bool virDomainNumatuneHasPlacementAuto(virDomainNuma *numatune);
205 
206 bool virDomainNumatuneHasPerNodeBinding(virDomainNuma *numatune);
207 
208 int virDomainNumatuneSpecifiedMaxNode(virDomainNuma *numatune);
209 
210 bool virDomainNumatuneNodesetIsAvailable(virDomainNuma *numatune,
211                                          virBitmap *auto_nodeset);
212 
213 bool virDomainNumatuneNodeSpecified(virDomainNuma *numatune,
214                                     int cellid);
215 
216 int virDomainNumaDefParseXML(virDomainNuma *def, xmlXPathContextPtr ctxt);
217 int virDomainNumaDefFormatXML(virBuffer *buf, virDomainNuma *def);
218 int virDomainNumaDefValidate(const virDomainNuma *def);
219 
220 unsigned int virDomainNumaGetCPUCountTotal(virDomainNuma *numa);
221 
222 int virDomainNumaFillCPUsInNode(virDomainNuma *numa, size_t node,
223                                 unsigned int maxCpus);
224 
225 bool virDomainNumaHasHMAT(const virDomainNuma *numa);
226 
227 size_t virDomainNumaGetNodeCacheCount(const virDomainNuma *numa,
228                                        size_t node);
229 
230 int virDomainNumaGetNodeCache(const virDomainNuma *numa,
231                               size_t node,
232                               size_t cache,
233                               unsigned int *level,
234                               unsigned int *size,
235                               unsigned int *line,
236                               virNumaCacheAssociativity *associativity,
237                               virNumaCachePolicy *policy);
238 
239 ssize_t virDomainNumaGetNodeInitiator(const virDomainNuma *numa,
240                                       size_t node);
241 
242 size_t virDomainNumaGetInterconnectsCount(const virDomainNuma *numa);
243 
244 int virDomainNumaGetInterconnect(const virDomainNuma *numa,
245                                  size_t i,
246                                  virNumaInterconnectType *type,
247                                  unsigned int *initiator,
248                                  unsigned int *target,
249                                  unsigned int *cache,
250                                  virMemoryLatency *accessType,
251                                  unsigned long *value);
252 
253 typedef struct _virNumaDistance virNumaDistance;
254 struct _virNumaDistance {
255     unsigned int value; /* locality value for node i->j or j->i */
256     unsigned int cellid;
257 };
258 
259 void virNumaDistanceFormat(virBuffer *buf,
260                            const virNumaDistance *distances,
261                            size_t ndistances);
262 
263 typedef struct _virNumaCache virNumaCache;
264 struct _virNumaCache {
265     unsigned int level; /* cache level */
266     unsigned int size;  /* cache size */
267     unsigned int line;  /* line size, !!! in bytes !!! */
268     virNumaCacheAssociativity associativity; /* cache associativity */
269     virNumaCachePolicy policy; /* cache policy */
270 };
271 
272 void virNumaCacheFormat(virBuffer *buf,
273                         const virNumaCache *caches,
274                         size_t ncaches);
275 
276 typedef struct _virNumaInterconnect virNumaInterconnect;
277 struct _virNumaInterconnect {
278     virNumaInterconnectType type;  /* whether structure describes latency
279                                       or bandwidth */
280     unsigned int initiator; /* the initiator NUMA node */
281     unsigned int target;    /* the target NUMA node */
282     unsigned int cache;     /* the target cache on @target; if 0 then the
283                                memory on @target */
284     virMemoryLatency accessType;  /* what type of access is defined */
285     unsigned long value;    /* value itself */
286 };
287 
288 void virNumaInterconnectFormat(virBuffer *buf,
289                                const virNumaInterconnect *interconnects,
290                                size_t ninterconnects);
291