Coverage Report

Created: 2026-02-14 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/hwloc/include/hwloc/plugins.h
Line
Count
Source
1
/*
2
 * SPDX-License-Identifier: BSD-3-Clause
3
 * Copyright © 2013-2026 Inria.  All rights reserved.
4
 * Copyright © 2016 Cisco Systems, Inc.  All rights reserved.
5
 * Copyright © 2025 Siemens Corporation and/or its affiliates.  All rights reserved.
6
 * See COPYING in top-level directory.
7
 */
8
9
#ifndef HWLOC_PLUGINS_H
10
#define HWLOC_PLUGINS_H
11
12
/** \file
13
 * \brief Public interface for building hwloc plugins.
14
 */
15
16
struct hwloc_backend;
17
18
#include "hwloc.h"
19
20
#ifdef HWLOC_INSIDE_PLUGIN
21
/* needed for hwloc_plugin_check_namespace() */
22
#ifdef HWLOC_HAVE_LTDL
23
#include <ltdl.h>
24
#elif !defined(HWLOC_WIN_SYS)
25
#include <dlfcn.h>
26
#endif
27
#endif
28
29
30
31
/** \defgroup hwlocality_disc_components Components and Plugins: Discovery components and backends
32
 *
33
 * \note These structures and functions may change when ::HWLOC_COMPONENT_ABI is modified.
34
 *
35
 * @{
36
 */
37
38
/** \brief Discovery component structure
39
 *
40
 * This is the major kind of components, taking care of the discovery.
41
 * They are registered by generic components, either statically-built or as plugins.
42
 */
43
struct hwloc_disc_component {
44
  /** \brief Name.
45
   * If this component is built as a plugin, this name does not have to match the plugin filename.
46
   */
47
  const char *name;
48
49
  /** \brief Discovery phases performed by this component.
50
   * OR'ed set of ::hwloc_disc_phase_t
51
   */
52
  unsigned phases;
53
54
  /** \brief Component phases to exclude, as an OR'ed set of ::hwloc_disc_phase_t.
55
   *
56
   * For a GLOBAL component, this usually includes all other phases (\c ~UL).
57
   *
58
   * Other components only exclude types that may bring conflicting
59
   * topology information. MISC components should likely not be excluded
60
   * since they usually bring non-primary additional information.
61
   */
62
  unsigned excluded_phases;
63
64
  /** \brief Instantiate callback to create a backend from the component.
65
   * Parameters data1, data2, data3 are NULL except for components
66
   * that have special enabling routines such as hwloc_topology_set_xml(). */
67
  struct hwloc_backend * (*instantiate)(struct hwloc_topology *topology, struct hwloc_disc_component *component, unsigned excluded_phases, const void *data1, const void *data2, const void *data3);
68
69
  /** \brief Component priority.
70
   * Used to sort topology->components, higher priority first.
71
   * Also used to decide between two components with the same name.
72
   *
73
   * Usual values are
74
   * 50 for native OS (or platform) components,
75
   * 45 for x86,
76
   * 40 for no-OS fallback,
77
   * 30 for global components (xml, synthetic),
78
   * 20 for pci,
79
   * 10 for other misc components (opencl etc.).
80
   */
81
  unsigned priority;
82
83
  /** \brief Enabled by default.
84
   * If unset, if will be disabled unless explicitly requested.
85
   */
86
  unsigned enabled_by_default;
87
88
  /** \private Used internally to list components by priority on topology->components
89
   * (the component structure is usually read-only,
90
   *  the core copies it before using this field for queueing)
91
   */
92
  struct hwloc_disc_component * next;
93
};
94
95
/** \brief Discovery phase */
96
typedef enum hwloc_disc_phase_e {
97
  /** \brief xml or synthetic, platform-specific components.
98
   * Discovers everything including CPU, memory, I/O and everything else.
99
   * A component with a Global phase usually excludes all other phases.
100
   * \hideinitializer */
101
  HWLOC_DISC_PHASE_GLOBAL = (1U<<0),
102
103
  /** \brief CPU discovery.
104
   * \hideinitializer */
105
  HWLOC_DISC_PHASE_CPU = (1U<<1),
106
107
  /** \brief Attach memory to existing CPU objects.
108
   * \hideinitializer */
109
  HWLOC_DISC_PHASE_MEMORY = (1U<<2),
110
111
  /** \brief Attach PCI devices and bridges to existing CPU objects.
112
   * \hideinitializer */
113
  HWLOC_DISC_PHASE_PCI = (1U<<3),
114
115
  /** \brief I/O discovery that requires PCI devices (OS devices such as OpenCL, CUDA, etc.).
116
   * \hideinitializer */
117
  HWLOC_DISC_PHASE_IO = (1U<<4),
118
119
  /** \brief Misc objects that gets added below anything else.
120
   * \hideinitializer */
121
  HWLOC_DISC_PHASE_MISC = (1U<<5),
122
123
  /** \brief Annotating existing objects, adding distances, etc.
124
   * \hideinitializer */
125
  HWLOC_DISC_PHASE_ANNOTATE = (1U<<6),
126
127
  /** \brief Annotating existing objects with a OS/hardware independent things,
128
   * for instance converting PCI vendor/model IDs into strings.
129
   * \hideinitializer */
130
  HWLOC_DISC_PHASE_ANNOTATE_INDEPENDENT = (1U<<7),
131
132
  /** \brief Final tweaks to a ready-to-use topology.
133
   * This phase runs once the topology is loaded, before it is returned to the topology.
134
   * Hence it may only use the main hwloc API for modifying the topology,
135
   * for instance by restricting it, adding info attributes, etc.
136
   * \hideinitializer */
137
  HWLOC_DISC_PHASE_TWEAK = (1U<<8)
138
} hwloc_disc_phase_t;
139
140
/** \brief Discovery status flags */
141
enum hwloc_disc_status_flag_e {
142
  /** \brief The sets of allowed resources were already retrieved \hideinitializer */
143
  HWLOC_DISC_STATUS_FLAG_GOT_ALLOWED_RESOURCES = (1UL<<1)
144
};
145
146
/** \brief Discovery status structure
147
 *
148
 * Used by the core and backends to inform about what has been/is being done
149
 * during the discovery process.
150
 */
151
struct hwloc_disc_status {
152
  /** \brief The current discovery phase that is performed.
153
   * Must match one of the phases in the component phases field.
154
   */
155
  hwloc_disc_phase_t phase;
156
157
  /** \brief Dynamically excluded phases.
158
   * If a component decides during discovery that some phases are no longer needed.
159
   */
160
  unsigned excluded_phases;
161
162
  /** \brief OR'ed set of ::hwloc_disc_status_flag_e */
163
  unsigned long flags;
164
};
165
166
/** \brief Discovery backend structure
167
 *
168
 * A backend is the instantiation of a discovery component.
169
 * When a component gets enabled for a topology,
170
 * its instantiate() callback creates a backend.
171
 *
172
 * hwloc_backend_alloc() initializes all fields to default values
173
 * that the component may change (except "component" and "next")
174
 * before enabling the backend with hwloc_backend_enable().
175
 *
176
 * Most backends assume that the topology is_thissystem flag is
177
 * set because they talk to the underlying operating system.
178
 * However they may still be used in topologies without the
179
 * is_thissystem flag for debugging reasons.
180
 * In practice, they are usually auto-disabled in such cases
181
 * (excluded by xml or synthetic backends, or by environment
182
 *  variables when changing the Linux fsroot or the x86 cpuid path).
183
 */
184
struct hwloc_backend {
185
  /** \private Reserved for the core, set by hwloc_backend_alloc() */
186
  struct hwloc_disc_component * component;
187
  /** \private Reserved for the core, set by hwloc_backend_enable() */
188
  struct hwloc_topology * topology;
189
  /** \private Reserved for the core. Set to 1 if forced through envvar, 0 otherwise. */
190
  int envvar_forced;
191
  /** \private Reserved for the core. Used internally to list backends topology->backends. */
192
  struct hwloc_backend * next;
193
194
  /** \brief Discovery phases performed by this component, possibly without some of them if excluded by other components.
195
   * OR'ed set of ::hwloc_disc_phase_t
196
   */
197
  unsigned phases;
198
199
  /** \brief Backend flags, currently always 0. */
200
  unsigned long flags;
201
202
  /** \brief Backend-specific 'is_thissystem' property.
203
   * Set to 0 if the backend disables the thissystem flag for this topology
204
   * (e.g. loading from xml or synthetic string,
205
   *  or using a different fsroot on Linux, or a x86 CPUID dump).
206
   * Set to -1 if the backend doesn't care (default).
207
   */
208
  int is_thissystem;
209
210
  /** \brief Callback for freeing things stored inside the private data.
211
   * May be NULL.
212
   */
213
  void (*disable)(struct hwloc_backend *backend);
214
215
  /** \brief Main discovery callback.
216
   * returns -1 on error, either because it couldn't add its objects ot the existing topology,
217
   * or because of an actual discovery/gathering failure.
218
   * May be NULL.
219
   */
220
  int (*discover)(struct hwloc_backend *backend, struct hwloc_disc_status *status);
221
222
  /** \brief Callback to retrieve the locality of a PCI object.
223
   * Called by the PCI core when attaching PCI hierarchy to CPU objects.
224
   * May be NULL.
225
   */
226
  int (*get_pci_busid_cpuset)(struct hwloc_backend *backend, struct hwloc_pcidev_attr_s *busid, hwloc_bitmap_t cpuset);
227
};
228
229
/** \brief Return the private data pointer at the end of a backend structure. */
230
#define HWLOC_BACKEND_PRIVATE_DATA(_backend) (void*)(((char*)(_backend)) + sizeof(struct hwloc_backend))
231
232
/** \brief Allocate a backend structure, set good default values, initialize backend->component and topology, etc.
233
 * The caller will then modify whatever needed, and call hwloc_backend_enable().
234
 * If \p private_data_size is positive, additional space is allocated at the end
235
 * of the structure for storing backend private data. That space may be obtained
236
 * with HWLOC_BACKEND_PRIVATE_DATA() and may be freely modified by the backend.
237
 */
238
HWLOC_DECLSPEC struct hwloc_backend * hwloc_backend_alloc(struct hwloc_topology *topology, struct hwloc_disc_component *component, unsigned long private_data_size);
239
240
/** \brief Enable a previously allocated and setup backend. */
241
HWLOC_DECLSPEC int hwloc_backend_enable(struct hwloc_backend *backend);
242
243
/** @} */
244
245
246
247
248
/** \defgroup hwlocality_generic_components Components and Plugins: Generic components
249
 *
250
 * \note These structures and functions may change when ::HWLOC_COMPONENT_ABI is modified.
251
 *
252
 * @{
253
 */
254
255
/** \brief Generic component type */
256
typedef enum hwloc_component_type_e {
257
  /** \brief The data field must point to a struct hwloc_disc_component. */
258
  HWLOC_COMPONENT_TYPE_DISC,
259
260
  /** \brief The data field must point to a struct hwloc_xml_component. */
261
  HWLOC_COMPONENT_TYPE_XML
262
} hwloc_component_type_t;
263
264
/** \brief Generic component structure
265
 *
266
 * Generic components structure, either statically listed by configure in static-components.h
267
 * or dynamically loaded as a plugin.
268
 */
269
struct hwloc_component {
270
  /** \brief Component ABI version, set to ::HWLOC_COMPONENT_ABI */
271
  unsigned abi;
272
273
  /** \brief Process-wide component initialization callback.
274
   *
275
   * This optional callback is called when the component is registered
276
   * to the hwloc core (after loading the plugin).
277
   *
278
   * When the component is built as a plugin, this callback
279
   * should call hwloc_check_plugin_namespace()
280
   * and return an negative error code on error.
281
   *
282
   * \p flags is always 0 for now.
283
   *
284
   * \return 0 on success, or a negative code on error.
285
   *
286
   * \note If the component uses ltdl for loading its own plugins,
287
   * it should load/unload them only in init() and finalize(),
288
   * to avoid race conditions with hwloc's use of ltdl.
289
   */
290
  int (*init)(unsigned long flags);
291
292
  /** \brief Process-wide component termination callback.
293
   *
294
   * This optional callback is called after unregistering the component
295
   * from the hwloc core (before unloading the plugin).
296
   *
297
   * \p flags is always 0 for now.
298
   *
299
   * \note If the component uses ltdl for loading its own plugins,
300
   * it should load/unload them only in init() and finalize(),
301
   * to avoid race conditions with hwloc's use of ltdl.
302
   */
303
  void (*finalize)(unsigned long flags);
304
305
  /** \brief Component type */
306
  hwloc_component_type_t type;
307
308
  /** \brief Component flags, unused for now */
309
  unsigned long flags;
310
311
  /** \brief Component data, pointing to a struct hwloc_disc_component or struct hwloc_xml_component. */
312
  void * data;
313
};
314
315
/** \brief Make sure that plugins can lookup core symbols.
316
 *
317
 * This is a sanity check to avoid lazy-lookup failures when libhwloc
318
 * is loaded within a plugin, and later tries to load its own plugins.
319
 * This may fail (and abort the program) if libhwloc symbols are in a
320
 * private namespace.
321
 *
322
 * \return 0 on success.
323
 * \return -1 if the plugin cannot be successfully loaded. The caller
324
 * plugin init() callback should return a negative error code as well.
325
 *
326
 * Plugins should call this function in their init() callback to avoid
327
 * later crashes if lazy symbol resolution is used by the upper layer that
328
 * loaded hwloc (e.g. OpenCL implementations using dlopen with RTLD_LAZY).
329
 *
330
 * \note The build system must define HWLOC_INSIDE_PLUGIN if and only if
331
 * building the caller as a plugin.
332
 *
333
 * \note This function should remain inline so plugins can call it even
334
 * when they cannot find libhwloc symbols.
335
 */
336
static __hwloc_inline int
337
hwloc_plugin_check_namespace(const char *pluginname __hwloc_attribute_unused, const char *symbol __hwloc_attribute_unused)
338
0
{
339
0
#ifdef HWLOC_INSIDE_PLUGIN
340
0
  void *sym;
341
0
#ifdef HWLOC_HAVE_LTDL
342
0
  lt_dlhandle handle = lt_dlopen(NULL);
343
0
#elif defined(HWLOC_WIN_SYS)
344
0
  HMODULE handle = GetModuleHandleA(NULL);
345
0
#else
346
0
  void *handle = dlopen(NULL, RTLD_NOW|RTLD_LOCAL);
347
0
#endif
348
0
  if (!handle)
349
0
    /* cannot check, assume things will work */
350
0
    return 0;
351
0
#ifdef HWLOC_HAVE_LTDL
352
0
  sym = lt_dlsym(handle, symbol);
353
0
  lt_dlclose(handle);
354
0
#elif defined(HWLOC_WIN_SYS)
355
0
  sym = GetModuleHandleA("hwloc.dll");
356
0
  FreeLibrary(handle);
357
0
#else
358
0
  sym = dlsym(handle, symbol);
359
0
  dlclose(handle);
360
0
#endif
361
0
  if (!sym) {
362
0
    static int verboseenv_checked = 0;
363
0
    static int verboseenv_value = 0;
364
0
    if (!verboseenv_checked) {
365
0
      const char *verboseenv = getenv("HWLOC_PLUGINS_VERBOSE");
366
0
      verboseenv_value = verboseenv ? atoi(verboseenv) : 0;
367
0
      verboseenv_checked = 1;
368
0
    }
369
0
    if (verboseenv_value)
370
0
      fprintf(stderr, "Plugin `%s' disabling itself because it cannot find the `%s' core symbol.\n",
371
0
        pluginname, symbol);
372
0
    return -1;
373
0
  }
374
0
#endif /* HWLOC_INSIDE_PLUGIN */
375
0
  return 0;
376
0
}
Unexecuted instantiation: hwloc_fuzzer.c:hwloc_plugin_check_namespace
Unexecuted instantiation: base64.c:hwloc_plugin_check_namespace
377
378
/** @} */
379
380
381
382
383
/** \defgroup hwlocality_components_core_funcs Components and Plugins: Core functions to be used by components
384
 *
385
 * \note These structures and functions may change when ::HWLOC_COMPONENT_ABI is modified.
386
 *
387
 * @{
388
 */
389
390
/** \brief Get the mask of error messages to display
391
 *
392
 * The mask is a OR'ed set of HWLOC_SHOWMSG_* as defined below.
393
 *
394
 * By default, only critical errors are shown.
395
 * May be configured with the HWLOC_SHOW_ERRORS environment variable
396
 * lstopo enables all error messages (HWLOC_SHOW_ERRORS=all).
397
 * hwloc-bind enables binding error messages (HWLOC_SHOW_ERRORS=bind).
398
 * See \ref envvar_verbose
399
 *
400
 * Callers should rather use HWLOC_SHOW_ERRORS() to directly check
401
 * if some kind of messages are enabled.
402
 */
403
HWLOC_DECLSPEC unsigned long hwloc_show_errors_mask(void);
404
405
#define HWLOC_SHOW_ERRORS(_flag) (hwloc_show_errors_mask() & (_flag))
406
407
#define HWLOC_SHOWMSG_CRITICAL   (1UL<<0)
408
/* Kinds of messages: failure to initialize CUDA, etc.
409
 * At least one of these should be passed to HWLOC_SHOW_ERRORS() */
410
#define HWLOC_SHOWMSG_BIND       (1UL<<1) /* binding */
411
#define HWLOC_SHOWMSG_SYNTHETIC  (1UL<<2) /* synthetic */
412
#define HWLOC_SHOWMSG_XML        (1UL<<3) /* XML */
413
#define HWLOC_SHOWMSG_COMPONENTS (1UL<<4) /* Components */
414
#define HWLOC_SHOWMSG_PLUGINS    (1UL<<5) /* Plugins */
415
#define HWLOC_SHOWMSG_RSMI       (1UL<<6) /* RSMI */
416
#define HWLOC_SHOWMSG_CUDA       (1UL<<7) /* CUDA */
417
#define HWLOC_SHOWMSG_NVML       (1UL<<8) /* NVML */
418
#define HWLOC_SHOWMSG_L0         (1UL<<9) /* L0 */
419
#define HWLOC_SHOWMSG_OPENCL     (1UL<<10) /* OpenCL */
420
#define HWLOC_SHOWMSG_GL         (1UL<<11) /* GL */
421
#define HWLOC_SHOWMSG_OS         (1UL<<12) /* Operating system */
422
#define HWLOC_SHOWMSG_PCI        (1UL<<13) /* PCI */
423
#define HWLOC_SHOWMSG_CORE       (1UL<<14) /* Issues in hwloc core */
424
#define HWLOC_SHOWMSG_MISC       (1UL<<15) /* Misc messages that don't belong anywhere else */
425
#define HWLOC_SHOWMSG_USER       (1UL<<16) /* Error caused by invalid user-given information (environment variables, etc) */
426
/* all messages */
427
#define HWLOC_SHOWMSG_ALL        (~0UL)
428
429
430
/** \brief Add an object to the topology.
431
 *
432
 * Insert new object \p obj in the topology starting under existing object \p root
433
 * (if \c NULL, the topology root object is used).
434
 *
435
 * It is sorted along the tree of other objects according to the inclusion of
436
 * cpusets, to eventually be added as a child of the smallest object including
437
 * this object.
438
 *
439
 * If the cpuset is empty, the type of the object (and maybe some attributes)
440
 * must be enough to find where to insert the object. This is especially true
441
 * for NUMA nodes with memory and no CPUs.
442
 *
443
 * The given object should not have children.
444
 *
445
 * This shall only be called before levels are built.
446
 *
447
 * The caller should check whether the object type is filtered-out before calling this function.
448
 *
449
 * The topology cpuset/nodesets will be enlarged to include the object sets.
450
 *
451
 * \p reason is a unique string identifying where and why this insertion call was performed
452
 * (it will be displayed in case of internal insertion error).
453
 *
454
 * Returns the object on success.
455
 * Returns NULL and frees obj on error.
456
 * Returns another object and frees obj if it was merged with an identical pre-existing object.
457
 */
458
HWLOC_DECLSPEC hwloc_obj_t
459
hwloc__insert_object_by_cpuset(struct hwloc_topology *topology, hwloc_obj_t root,
460
                               hwloc_obj_t obj, const char *reason);
461
462
/** \brief Insert an object somewhere in the topology.
463
 *
464
 * It is added as the last child of the given parent.
465
 * The cpuset is completely ignored, so strange objects such as I/O devices should
466
 * preferably be inserted with this.
467
 *
468
 * When used for "normal" children with cpusets (when importing from XML
469
 * when duplicating a topology), the caller should make sure that:
470
 * - children are inserted in order,
471
 * - children cpusets do not intersect.
472
 *
473
 * The given object may have normal, I/O or Misc children, as long as they are in order as well.
474
 * These children must have valid parent and next_sibling pointers.
475
 *
476
 * The caller should check whether the object type is filtered-out before calling this function.
477
 */
478
HWLOC_DECLSPEC void hwloc_insert_object_by_parent(struct hwloc_topology *topology, hwloc_obj_t parent, hwloc_obj_t obj);
479
480
/** \brief Allocate and initialize an object of the given type and physical index.
481
 *
482
 * If \p os_index is unknown or irrelevant, use \c HWLOC_UNKNOWN_INDEX.
483
 */
484
HWLOC_DECLSPEC hwloc_obj_t hwloc_alloc_setup_object(hwloc_topology_t topology, hwloc_obj_type_t type, unsigned os_index);
485
486
/** \brief Setup object cpusets/nodesets by OR'ing its children.
487
 *
488
 * Used when adding an object late in the topology.
489
 * Will update the new object by OR'ing all its new children sets.
490
 *
491
 * Used when PCI backend adds a hostbridge parent, when distances
492
 * add a new Group, etc.
493
 */
494
HWLOC_DECLSPEC int hwloc_obj_add_children_sets(hwloc_obj_t obj);
495
496
/** \brief Request a reconnection of children and levels in the topology.
497
 *
498
 * May be used by backends during discovery if they need arrays or lists
499
 * of object within levels or children to be fully connected.
500
 *
501
 * \p flags is currently unused, must 0.
502
 */
503
HWLOC_DECLSPEC int hwloc_topology_reconnect(hwloc_topology_t topology, unsigned long flags __hwloc_attribute_unused);
504
505
/** @} */
506
507
508
509
510
/** \defgroup hwlocality_components_filtering Components and Plugins: Filtering objects
511
 *
512
 * \note These structures and functions may change when ::HWLOC_COMPONENT_ABI is modified.
513
 *
514
 * @{
515
 */
516
517
/** \brief Check whether the given PCI device classid is important.
518
 *
519
 * \return 1 if important, 0 otherwise.
520
 */
521
static __hwloc_inline int
522
hwloc_filter_check_pcidev_subtype_important(unsigned classid)
523
0
{
524
0
  unsigned baseclass = classid >> 8;
525
0
  return (baseclass == 0x03 /* PCI_BASE_CLASS_DISPLAY */
526
0
    || baseclass == 0x02 /* PCI_BASE_CLASS_NETWORK */
527
0
    || baseclass == 0x01 /* PCI_BASE_CLASS_STORAGE */
528
0
    || baseclass == 0x00 /* Unclassified, for Atos/Bull BXI */
529
0
    || baseclass == 0x0b /* PCI_BASE_CLASS_PROCESSOR */
530
0
    || classid == 0x0c04 /* PCI_CLASS_SERIAL_FIBER */
531
0
    || classid == 0x0c06 /* PCI_CLASS_SERIAL_INFINIBAND */
532
0
          || classid == 0x0502 /* PCI_CLASS_MEMORY_CXL */
533
0
          || baseclass == 0x06 /* PCI_BASE_CLASS_BRIDGE with non-PCI downstream. the core will drop the useless ones later */
534
0
    || baseclass == 0x12 /* Processing Accelerators */);
535
0
}
Unexecuted instantiation: hwloc_fuzzer.c:hwloc_filter_check_pcidev_subtype_important
Unexecuted instantiation: base64.c:hwloc_filter_check_pcidev_subtype_important
536
537
/** \brief Check whether the given OS device subtype is important.
538
 *
539
 * \return 1 if important, 0 otherwise.
540
 */
541
static __hwloc_inline int
542
hwloc_filter_check_osdev_subtype_important(hwloc_obj_osdev_types_t subtype)
543
0
{
544
0
  return (subtype && subtype != HWLOC_OBJ_OSDEV_DMA);
545
0
}
Unexecuted instantiation: hwloc_fuzzer.c:hwloc_filter_check_osdev_subtype_important
Unexecuted instantiation: base64.c:hwloc_filter_check_osdev_subtype_important
546
547
/** \brief Check whether a non-I/O object type should be filtered-out.
548
 *
549
 * Cannot be used for I/O objects.
550
 *
551
 * \return 1 if the object type should be kept, 0 otherwise.
552
 */
553
static __hwloc_inline int
554
hwloc_filter_check_keep_object_type(hwloc_topology_t topology, hwloc_obj_type_t type)
555
0
{
556
0
  enum hwloc_type_filter_e filter = HWLOC_TYPE_FILTER_KEEP_NONE;
557
0
  hwloc_topology_get_type_filter(topology, type, &filter);
558
0
  assert(filter != HWLOC_TYPE_FILTER_KEEP_IMPORTANT); /* IMPORTANT only used for I/O */
559
0
  return filter == HWLOC_TYPE_FILTER_KEEP_NONE ? 0 : 1;
560
0
}
Unexecuted instantiation: hwloc_fuzzer.c:hwloc_filter_check_keep_object_type
Unexecuted instantiation: base64.c:hwloc_filter_check_keep_object_type
561
562
/** \brief Check whether the given object should be filtered-out.
563
 *
564
 * \return 1 if the object type should be kept, 0 otherwise.
565
 */
566
static __hwloc_inline int
567
hwloc_filter_check_keep_object(hwloc_topology_t topology, hwloc_obj_t obj)
568
0
{
569
0
  hwloc_obj_type_t type = obj->type;
570
0
  enum hwloc_type_filter_e filter = HWLOC_TYPE_FILTER_KEEP_NONE;
571
0
  hwloc_topology_get_type_filter(topology, type, &filter);
572
0
  if (filter == HWLOC_TYPE_FILTER_KEEP_NONE)
573
0
    return 0;
574
0
  if (filter == HWLOC_TYPE_FILTER_KEEP_IMPORTANT) {
575
0
    if (type == HWLOC_OBJ_PCI_DEVICE)
576
0
      return hwloc_filter_check_pcidev_subtype_important(obj->attr->pcidev.class_id);
577
0
    if (type == HWLOC_OBJ_OS_DEVICE)
578
0
      return hwloc_filter_check_osdev_subtype_important(obj->attr->osdev.types);
579
0
  }
580
0
  return 1;
581
0
}
Unexecuted instantiation: hwloc_fuzzer.c:hwloc_filter_check_keep_object
Unexecuted instantiation: base64.c:hwloc_filter_check_keep_object
582
583
/** @} */
584
585
586
587
588
/** \defgroup hwlocality_components_pcidisc Components and Plugins: helpers for PCI discovery
589
 *
590
 * \note These structures and functions may change when ::HWLOC_COMPONENT_ABI is modified.
591
 *
592
 * @{
593
 */
594
595
/** \brief Return the offset of the given capability in the PCI config space buffer
596
 *
597
 * This function requires a 256-bytes config space. Unknown/unavailable bytes should be set to 0xff.
598
 */
599
HWLOC_DECLSPEC unsigned hwloc_pcidisc_find_cap(const unsigned char *config, unsigned cap);
600
601
/** \brief Fill linkspeed by reading the PCI config space where PCI_CAP_ID_EXP is at position offset.
602
 *
603
 * Needs 20 bytes of EXP capability block starting at offset in the config space
604
 * for registers up to link status.
605
 */
606
HWLOC_DECLSPEC int hwloc_pcidisc_find_linkspeed(const unsigned char *config, unsigned offset, float *linkspeed);
607
608
/** \brief Return the hwloc object type (PCI device or Bridge) for the given class and configuration space.
609
 *
610
 * This function requires 16 bytes of common configuration header at the beginning of config.
611
 */
612
HWLOC_DECLSPEC hwloc_obj_type_t hwloc_pcidisc_check_bridge_type(unsigned device_class, const unsigned char *config);
613
614
/** \brief Fills the attributes of the given PCI bridge using the given PCI config space.
615
 *
616
 * This function requires 32 bytes of common configuration header at the beginning of config.
617
 *
618
 * Returns -1 and destroys /p obj if bridge fields are invalid.
619
 */
620
HWLOC_DECLSPEC int hwloc_pcidisc_find_bridge_buses(unsigned domain, unsigned bus, unsigned dev, unsigned func,
621
               unsigned *secondary_busp, unsigned *subordinate_busp,
622
               const unsigned char *config);
623
624
/** \brief Insert a PCI object in the given PCI tree by looking at PCI bus IDs.
625
 *
626
 * If \p treep points to \c NULL, the new object is inserted there.
627
 */
628
HWLOC_DECLSPEC void hwloc_pcidisc_tree_insert_by_busid(struct hwloc_obj **treep, struct hwloc_obj *obj);
629
630
/** \brief Add some hostbridges on top of the given tree of PCI objects and attach them to the topology.
631
 *
632
 * Other backends may lookup PCI objects or localities (for instance to attach OS devices)
633
 * by using hwloc_pcidisc_find_by_busid() or hwloc_pcidisc_find_busid_parent().
634
 */
635
HWLOC_DECLSPEC int hwloc_pcidisc_tree_attach(struct hwloc_topology *topology, struct hwloc_obj *tree);
636
637
/** @} */
638
639
640
641
642
/** \defgroup hwlocality_components_pcifind Components and Plugins: finding PCI objects during other discoveries
643
 *
644
 * \note These structures and functions may change when ::HWLOC_COMPONENT_ABI is modified.
645
 *
646
 * @{
647
 */
648
649
/** \brief Find the object or a parent of a PCI bus ID.
650
 *
651
 * When attaching a new object (typically an OS device) whose locality
652
 * is specified by PCI bus ID, this function returns the PCI object
653
 * to use as a parent for attaching.
654
 *
655
 * If the exact PCI device with this bus ID exists, it is returned.
656
 * Otherwise (for instance if it was filtered out), the function returns
657
 * another object with similar locality (for instance a parent bridge,
658
 * or the local CPU Package).
659
 */
660
HWLOC_DECLSPEC struct hwloc_obj * hwloc_pci_find_parent_by_busid(struct hwloc_topology *topology, unsigned domain, unsigned bus, unsigned dev, unsigned func);
661
662
/** \brief Find the PCI device or bridge matching a PCI bus ID exactly.
663
 *
664
 * This is useful for adding specific information about some objects
665
 * based on their PCI id. When it comes to attaching objects based on
666
 * PCI locality, hwloc_pci_find_parent_by_busid() should be preferred.
667
 */
668
HWLOC_DECLSPEC struct hwloc_obj * hwloc_pci_find_by_busid(struct hwloc_topology *topology, unsigned domain, unsigned bus, unsigned dev, unsigned func);
669
670
671
/** @} */
672
673
674
675
676
/** \defgroup hwlocality_components_distances Components and Plugins: distances
677
 *
678
 * \note These structures and functions may change when ::HWLOC_COMPONENT_ABI is modified.
679
 *
680
 * @{
681
 */
682
683
/** \brief Handle to a new distances structure during its addition to the topology. */
684
typedef void * hwloc_backend_distances_add_handle_t;
685
686
/** \brief Create a new empty distances structure.
687
 *
688
 * This is identical to hwloc_distances_add_create()
689
 * but this variant is designed for backend inserting
690
 * distances during topology discovery.
691
 */
692
HWLOC_DECLSPEC hwloc_backend_distances_add_handle_t
693
hwloc_backend_distances_add_create(hwloc_topology_t topology,
694
                                   const char *name, unsigned long kind,
695
                                   unsigned long flags);
696
697
/** \brief Specify the objects and values in a new empty distances structure.
698
 *
699
 * This is similar to hwloc_distances_add_values()
700
 * but this variant is designed for backend inserting
701
 * distances during topology discovery.
702
 *
703
 * The only semantical difference is that \p objs and \p values
704
 * are not duplicated, but directly attached to the topology.
705
 * On success, these arrays are given to the core and should not
706
 * ever be freed by the caller anymore.
707
 */
708
HWLOC_DECLSPEC int
709
hwloc_backend_distances_add_values(hwloc_topology_t topology,
710
                                   hwloc_backend_distances_add_handle_t handle,
711
                                   unsigned nbobjs, hwloc_obj_t *objs,
712
                                   hwloc_uint64_t *values,
713
                                   unsigned long flags);
714
715
/** \brief Commit a new distances structure.
716
 *
717
 * This is similar to hwloc_distances_add_commit()
718
 * but this variant is designed for backend inserting
719
 * distances during topology discovery.
720
 */
721
HWLOC_DECLSPEC int
722
hwloc_backend_distances_add_commit(hwloc_topology_t topology,
723
                                   hwloc_backend_distances_add_handle_t handle,
724
                                   unsigned long flags);
725
726
/** @} */
727
728
729
730
731
#endif /* HWLOC_PLUGINS_H */