root/opal/mca/hwloc/hwloc201/hwloc/include/hwloc/plugins.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. hwloc_plugin_check_namespace
  2. hwloc_filter_check_pcidev_subtype_important
  3. hwloc_filter_check_osdev_subtype_important
  4. hwloc_filter_check_keep_object_type
  5. hwloc_filter_check_keep_object

   1 /*
   2  * Copyright © 2013-2017 Inria.  All rights reserved.
   3  * Copyright © 2016 Cisco Systems, Inc.  All rights reserved.
   4  * See COPYING in top-level directory.
   5  */
   6 
   7 #ifndef HWLOC_PLUGINS_H
   8 #define HWLOC_PLUGINS_H
   9 
  10 /** \file
  11  * \brief Public interface for building hwloc plugins.
  12  */
  13 
  14 struct hwloc_backend;
  15 
  16 #include <hwloc.h>
  17 #ifdef HWLOC_INSIDE_PLUGIN
  18 /* needed for hwloc_plugin_check_namespace() */
  19 #include <ltdl.h>
  20 #endif
  21 
  22 
  23 
  24 /** \defgroup hwlocality_disc_components Components and Plugins: Discovery components
  25  * @{
  26  */
  27 
  28 /** \brief Discovery component type */
  29 typedef enum hwloc_disc_component_type_e {
  30   /** \brief CPU-only discovery through the OS, or generic no-OS support.
  31    * \hideinitializer */
  32   HWLOC_DISC_COMPONENT_TYPE_CPU = (1<<0),
  33 
  34   /** \brief xml or synthetic,
  35    * platform-specific components such as bgq.
  36    * Anything the discovers CPU and everything else.
  37    * No misc backend is expected to complement a global component.
  38    * \hideinitializer */
  39   HWLOC_DISC_COMPONENT_TYPE_GLOBAL = (1<<1),
  40 
  41   /** \brief OpenCL, Cuda, etc.
  42    * \hideinitializer */
  43   HWLOC_DISC_COMPONENT_TYPE_MISC = (1<<2)
  44 } hwloc_disc_component_type_t;
  45 
  46 /** \brief Discovery component structure
  47  *
  48  * This is the major kind of components, taking care of the discovery.
  49  * They are registered by generic components, either statically-built or as plugins.
  50  */
  51 struct hwloc_disc_component {
  52   /** \brief Discovery component type */
  53   hwloc_disc_component_type_t type;
  54 
  55   /** \brief Name.
  56    * If this component is built as a plugin, this name does not have to match the plugin filename.
  57    */
  58   const char *name;
  59 
  60   /** \brief Component types to exclude, as an OR'ed set of ::hwloc_disc_component_type_e.
  61    *
  62    * For a GLOBAL component, this usually includes all other types (~0).
  63    *
  64    * Other components only exclude types that may bring conflicting
  65    * topology information. MISC components should likely not be excluded
  66    * since they usually bring non-primary additional information.
  67    */
  68   unsigned excludes;
  69 
  70   /** \brief Instantiate callback to create a backend from the component.
  71    * Parameters data1, data2, data3 are NULL except for components
  72    * that have special enabling routines such as hwloc_topology_set_xml(). */
  73   struct hwloc_backend * (*instantiate)(struct hwloc_disc_component *component, const void *data1, const void *data2, const void *data3);
  74 
  75   /** \brief Component priority.
  76    * Used to sort topology->components, higher priority first.
  77    * Also used to decide between two components with the same name.
  78    *
  79    * Usual values are
  80    * 50 for native OS (or platform) components,
  81    * 45 for x86,
  82    * 40 for no-OS fallback,
  83    * 30 for global components (xml, synthetic),
  84    * 20 for pci,
  85    * 10 for other misc components (opencl etc.).
  86    */
  87   unsigned priority;
  88 
  89   /** \brief Enabled by default.
  90    * If unset, if will be disabled unless explicitly requested.
  91    */
  92   unsigned enabled_by_default;
  93 
  94   /** \private Used internally to list components by priority on topology->components
  95    * (the component structure is usually read-only,
  96    *  the core copies it before using this field for queueing)
  97    */
  98   struct hwloc_disc_component * next;
  99 };
 100 
 101 /** @} */
 102 
 103 
 104 
 105 
 106 /** \defgroup hwlocality_disc_backends Components and Plugins: Discovery backends
 107  * @{
 108  */
 109 
 110 /** \brief Discovery backend structure
 111  *
 112  * A backend is the instantiation of a discovery component.
 113  * When a component gets enabled for a topology,
 114  * its instantiate() callback creates a backend.
 115  *
 116  * hwloc_backend_alloc() initializes all fields to default values
 117  * that the component may change (except "component" and "next")
 118  * before enabling the backend with hwloc_backend_enable().
 119  */
 120 struct hwloc_backend {
 121   /** \private Reserved for the core, set by hwloc_backend_alloc() */
 122   struct hwloc_disc_component * component;
 123   /** \private Reserved for the core, set by hwloc_backend_enable() */
 124   struct hwloc_topology * topology;
 125   /** \private Reserved for the core. Set to 1 if forced through envvar, 0 otherwise. */
 126   int envvar_forced;
 127   /** \private Reserved for the core. Used internally to list backends topology->backends. */
 128   struct hwloc_backend * next;
 129 
 130   /** \brief Backend flags, currently always 0. */
 131   unsigned long flags;
 132 
 133   /** \brief Backend-specific 'is_thissystem' property.
 134    * Set to 0 or 1 if the backend should enforce the thissystem flag when it gets enabled.
 135    * Set to -1 if the backend doesn't care (default). */
 136   int is_thissystem;
 137 
 138   /** \brief Backend private data, or NULL if none. */
 139   void * private_data;
 140   /** \brief Callback for freeing the private_data.
 141    * May be NULL.
 142    */
 143   void (*disable)(struct hwloc_backend *backend);
 144 
 145   /** \brief Main discovery callback.
 146    * returns -1 on error, either because it couldn't add its objects ot the existing topology,
 147    * or because of an actual discovery/gathering failure.
 148    * May be NULL.
 149    */
 150   int (*discover)(struct hwloc_backend *backend);
 151 
 152   /** \brief Callback used by the PCI backend to retrieve the locality of a PCI object from the OS/cpu backend.
 153    * May be NULL. */
 154   int (*get_pci_busid_cpuset)(struct hwloc_backend *backend, struct hwloc_pcidev_attr_s *busid, hwloc_bitmap_t cpuset);
 155 };
 156 
 157 /** \brief Allocate a backend structure, set good default values, initialize backend->component and topology, etc.
 158  * The caller will then modify whatever needed, and call hwloc_backend_enable().
 159  */
 160 HWLOC_DECLSPEC struct hwloc_backend * hwloc_backend_alloc(struct hwloc_disc_component *component);
 161 
 162 /** \brief Enable a previously allocated and setup backend. */
 163 HWLOC_DECLSPEC int hwloc_backend_enable(struct hwloc_topology *topology, struct hwloc_backend *backend);
 164 
 165 /** @} */
 166 
 167 
 168 
 169 
 170 /** \defgroup hwlocality_generic_components Components and Plugins: Generic components
 171  * @{
 172  */
 173 
 174 /** \brief Generic component type */
 175 typedef enum hwloc_component_type_e {
 176   /** \brief The data field must point to a struct hwloc_disc_component. */
 177   HWLOC_COMPONENT_TYPE_DISC,
 178 
 179   /** \brief The data field must point to a struct hwloc_xml_component. */
 180   HWLOC_COMPONENT_TYPE_XML
 181 } hwloc_component_type_t;
 182 
 183 /** \brief Generic component structure
 184  *
 185  * Generic components structure, either statically listed by configure in static-components.h
 186  * or dynamically loaded as a plugin.
 187  */
 188 struct hwloc_component {
 189   /** \brief Component ABI version, set to ::HWLOC_COMPONENT_ABI */
 190   unsigned abi;
 191 
 192   /** \brief Process-wide component initialization callback.
 193    *
 194    * This optional callback is called when the component is registered
 195    * to the hwloc core (after loading the plugin).
 196    *
 197    * When the component is built as a plugin, this callback
 198    * should call hwloc_check_plugin_namespace()
 199    * and return an negative error code on error.
 200    *
 201    * \p flags is always 0 for now.
 202    *
 203    * \return 0 on success, or a negative code on error.
 204    *
 205    * \note If the component uses ltdl for loading its own plugins,
 206    * it should load/unload them only in init() and finalize(),
 207    * to avoid race conditions with hwloc's use of ltdl.
 208    */
 209   int (*init)(unsigned long flags);
 210 
 211   /** \brief Process-wide component termination callback.
 212    *
 213    * This optional callback is called after unregistering the component
 214    * from the hwloc core (before unloading the plugin).
 215    *
 216    * \p flags is always 0 for now.
 217    *
 218    * \note If the component uses ltdl for loading its own plugins,
 219    * it should load/unload them only in init() and finalize(),
 220    * to avoid race conditions with hwloc's use of ltdl.
 221    */
 222   void (*finalize)(unsigned long flags);
 223 
 224   /** \brief Component type */
 225   hwloc_component_type_t type;
 226 
 227   /** \brief Component flags, unused for now */
 228   unsigned long flags;
 229 
 230   /** \brief Component data, pointing to a struct hwloc_disc_component or struct hwloc_xml_component. */
 231   void * data;
 232 };
 233 
 234 /** @} */
 235 
 236 
 237 
 238 
 239 /** \defgroup hwlocality_components_core_funcs Components and Plugins: Core functions to be used by components
 240  * @{
 241  */
 242 
 243 /** \brief Add an object to the topology.
 244  *
 245  * It is sorted along the tree of other objects according to the inclusion of
 246  * cpusets, to eventually be added as a child of the smallest object including
 247  * this object.
 248  *
 249  * If the cpuset is empty, the type of the object (and maybe some attributes)
 250  * must be enough to find where to insert the object. This is especially true
 251  * for NUMA nodes with memory and no CPUs.
 252  *
 253  * The given object should not have children.
 254  *
 255  * This shall only be called before levels are built.
 256  *
 257  * In case of error, hwloc_report_os_error() is called.
 258  *
 259  * The caller should check whether the object type is filtered-out before calling this function.
 260  *
 261  * The topology cpuset/nodesets will be enlarged to include the object sets.
 262  *
 263  * Returns the object on success.
 264  * Returns NULL and frees obj on error.
 265  * Returns another object and frees obj if it was merged with an identical pre-existing object.
 266  */
 267 HWLOC_DECLSPEC struct hwloc_obj *hwloc_insert_object_by_cpuset(struct hwloc_topology *topology, hwloc_obj_t obj);
 268 
 269 /** \brief Type of error callbacks during object insertion */
 270 typedef void (*hwloc_report_error_t)(const char * msg, int line);
 271 /** \brief Report an insertion error from a backend */
 272 HWLOC_DECLSPEC void hwloc_report_os_error(const char * msg, int line);
 273 /** \brief Check whether insertion errors are hidden */
 274 HWLOC_DECLSPEC int hwloc_hide_errors(void);
 275 
 276 /** \brief Add an object to the topology and specify which error callback to use.
 277  *
 278  * This function is similar to hwloc_insert_object_by_cpuset() but it allows specifying
 279  * where to start insertion from (if \p root is NULL, the topology root object is used),
 280  * and specifying the error callback.
 281  */
 282 HWLOC_DECLSPEC struct hwloc_obj *hwloc__insert_object_by_cpuset(struct hwloc_topology *topology, hwloc_obj_t root, hwloc_obj_t obj, hwloc_report_error_t report_error);
 283 
 284 /** \brief Insert an object somewhere in the topology.
 285  *
 286  * It is added as the last child of the given parent.
 287  * The cpuset is completely ignored, so strange objects such as I/O devices should
 288  * preferably be inserted with this.
 289  *
 290  * When used for "normal" children with cpusets (when importing from XML
 291  * when duplicating a topology), the caller should make sure that:
 292  * - children are inserted in order,
 293  * - children cpusets do not intersect.
 294  *
 295  * The given object may have normal, I/O or Misc children, as long as they are in order as well.
 296  * These children must have valid parent and next_sibling pointers.
 297  *
 298  * The caller should check whether the object type is filtered-out before calling this function.
 299  */
 300 HWLOC_DECLSPEC void hwloc_insert_object_by_parent(struct hwloc_topology *topology, hwloc_obj_t parent, hwloc_obj_t obj);
 301 
 302 /** \brief Allocate and initialize an object of the given type and physical index.
 303  *
 304  * If \p os_index is unknown or irrelevant, use \c HWLOC_UNKNOWN_INDEX.
 305  */
 306 HWLOC_DECLSPEC hwloc_obj_t hwloc_alloc_setup_object(hwloc_topology_t topology, hwloc_obj_type_t type, unsigned os_index);
 307 
 308 /** \brief Setup object cpusets/nodesets by OR'ing its children.
 309  *
 310  * Used when adding an object late in the topology.
 311  * Will update the new object by OR'ing all its new children sets.
 312  *
 313  * Used when PCI backend adds a hostbridge parent, when distances
 314  * add a new Group, etc.
 315  */
 316 HWLOC_DECLSPEC int hwloc_obj_add_children_sets(hwloc_obj_t obj);
 317 
 318 /** \brief Request a reconnection of children and levels in the topology.
 319  *
 320  * May be used by backends during discovery if they need arrays or lists
 321  * of object within levels or children to be fully connected.
 322  *
 323  * \p flags is currently unused, must 0.
 324  */
 325 HWLOC_DECLSPEC int hwloc_topology_reconnect(hwloc_topology_t topology, unsigned long flags __hwloc_attribute_unused);
 326 
 327 /** \brief Make sure that plugins can lookup core symbols.
 328  *
 329  * This is a sanity check to avoid lazy-lookup failures when libhwloc
 330  * is loaded within a plugin, and later tries to load its own plugins.
 331  * This may fail (and abort the program) if libhwloc symbols are in a
 332  * private namespace.
 333  *
 334  * \return 0 on success.
 335  * \return -1 if the plugin cannot be successfully loaded. The caller
 336  * plugin init() callback should return a negative error code as well.
 337  *
 338  * Plugins should call this function in their init() callback to avoid
 339  * later crashes if lazy symbol resolution is used by the upper layer that
 340  * loaded hwloc (e.g. OpenCL implementations using dlopen with RTLD_LAZY).
 341  *
 342  * \note The build system must define HWLOC_INSIDE_PLUGIN if and only if
 343  * building the caller as a plugin.
 344  *
 345  * \note This function should remain inline so plugins can call it even
 346  * when they cannot find libhwloc symbols.
 347  */
 348 static __hwloc_inline int
 349 hwloc_plugin_check_namespace(const char *pluginname __hwloc_attribute_unused, const char *symbol __hwloc_attribute_unused)
 350 {
 351 #ifdef HWLOC_INSIDE_PLUGIN
 352   lt_dlhandle handle;
 353   void *sym;
 354   handle = lt_dlopen(NULL);
 355   if (!handle)
 356     /* cannot check, assume things will work */
 357     return 0;
 358   sym = lt_dlsym(handle, symbol);
 359   lt_dlclose(handle);
 360   if (!sym) {
 361     static int verboseenv_checked = 0;
 362     static int verboseenv_value = 0;
 363     if (!verboseenv_checked) {
 364       const char *verboseenv = getenv("HWLOC_PLUGINS_VERBOSE");
 365       verboseenv_value = verboseenv ? atoi(verboseenv) : 0;
 366       verboseenv_checked = 1;
 367     }
 368     if (verboseenv_value)
 369       fprintf(stderr, "Plugin `%s' disabling itself because it cannot find the `%s' core symbol.\n",
 370               pluginname, symbol);
 371     return -1;
 372   }
 373 #endif /* HWLOC_INSIDE_PLUGIN */
 374   return 0;
 375 }
 376 
 377 /** @} */
 378 
 379 
 380 
 381 
 382 /** \defgroup hwlocality_components_filtering Components and Plugins: Filtering objects
 383  * @{
 384  */
 385 
 386 /** \brief Check whether the given PCI device classid is important.
 387  *
 388  * \return 1 if important, 0 otherwise.
 389  */
 390 static __hwloc_inline int
 391 hwloc_filter_check_pcidev_subtype_important(unsigned classid)
 392 {
 393   unsigned baseclass = classid >> 8;
 394   return (baseclass == 0x03 /* PCI_BASE_CLASS_DISPLAY */
 395           || baseclass == 0x02 /* PCI_BASE_CLASS_NETWORK */
 396           || baseclass == 0x01 /* PCI_BASE_CLASS_STORAGE */
 397           || baseclass == 0x0b /* PCI_BASE_CLASS_PROCESSOR */
 398           || classid == 0x0c04 /* PCI_CLASS_SERIAL_FIBER */
 399           || classid == 0x0c06 /* PCI_CLASS_SERIAL_INFINIBAND */
 400           || baseclass == 0x12 /* Processing Accelerators */);
 401 }
 402 
 403 /** \brief Check whether the given OS device subtype is important.
 404  *
 405  * \return 1 if important, 0 otherwise.
 406  */
 407 static __hwloc_inline int
 408 hwloc_filter_check_osdev_subtype_important(hwloc_obj_osdev_type_t subtype)
 409 {
 410   return (subtype != HWLOC_OBJ_OSDEV_DMA);
 411 }
 412 
 413 /** \brief Check whether a non-I/O object type should be filtered-out.
 414  *
 415  * Cannot be used for I/O objects.
 416  *
 417  * \return 1 if the object type should be kept, 0 otherwise.
 418  */
 419 static __hwloc_inline int
 420 hwloc_filter_check_keep_object_type(hwloc_topology_t topology, hwloc_obj_type_t type)
 421 {
 422   enum hwloc_type_filter_e filter = HWLOC_TYPE_FILTER_KEEP_NONE;
 423   hwloc_topology_get_type_filter(topology, type, &filter);
 424   assert(filter != HWLOC_TYPE_FILTER_KEEP_IMPORTANT); /* IMPORTANT only used for I/O */
 425   return filter == HWLOC_TYPE_FILTER_KEEP_NONE ? 0 : 1;
 426 }
 427 
 428 /** \brief Check whether the given object should be filtered-out.
 429  *
 430  * \return 1 if the object type should be kept, 0 otherwise.
 431  */
 432 static __hwloc_inline int
 433 hwloc_filter_check_keep_object(hwloc_topology_t topology, hwloc_obj_t obj)
 434 {
 435   hwloc_obj_type_t type = obj->type;
 436   enum hwloc_type_filter_e filter = HWLOC_TYPE_FILTER_KEEP_NONE;
 437   hwloc_topology_get_type_filter(topology, type, &filter);
 438   if (filter == HWLOC_TYPE_FILTER_KEEP_NONE)
 439     return 0;
 440   if (filter == HWLOC_TYPE_FILTER_KEEP_IMPORTANT) {
 441     if (type == HWLOC_OBJ_PCI_DEVICE)
 442       return hwloc_filter_check_pcidev_subtype_important(obj->attr->pcidev.class_id);
 443     if (type == HWLOC_OBJ_OS_DEVICE)
 444       return hwloc_filter_check_osdev_subtype_important(obj->attr->osdev.type);
 445   }
 446   return 1;
 447 }
 448 
 449 /** @} */
 450 
 451 
 452 
 453 
 454 /** \defgroup hwlocality_components_pcidisc Components and Plugins: helpers for PCI discovery
 455  * @{
 456  */
 457 
 458 /** \brief Return the offset of the given capability in the PCI config space buffer
 459  *
 460  * This function requires a 256-bytes config space. Unknown/unavailable bytes should be set to 0xff.
 461  */
 462 HWLOC_DECLSPEC unsigned hwloc_pcidisc_find_cap(const unsigned char *config, unsigned cap);
 463 
 464 /** \brief Fill linkspeed by reading the PCI config space where PCI_CAP_ID_EXP is at position offset.
 465  *
 466  * Needs 20 bytes of EXP capability block starting at offset in the config space
 467  * for registers up to link status.
 468  */
 469 HWLOC_DECLSPEC int hwloc_pcidisc_find_linkspeed(const unsigned char *config, unsigned offset, float *linkspeed);
 470 
 471 /** \brief Return the hwloc object type (PCI device or Bridge) for the given class and configuration space.
 472  *
 473  * This function requires 16 bytes of common configuration header at the beginning of config.
 474  */
 475 HWLOC_DECLSPEC hwloc_obj_type_t hwloc_pcidisc_check_bridge_type(unsigned device_class, const unsigned char *config);
 476 
 477 /** \brief Fills the attributes of the given PCI bridge using the given PCI config space.
 478  *
 479  * This function requires 32 bytes of common configuration header at the beginning of config.
 480  *
 481  * Returns -1 and destroys /p obj if bridge fields are invalid.
 482  */
 483 HWLOC_DECLSPEC int hwloc_pcidisc_setup_bridge_attr(hwloc_obj_t obj, const unsigned char *config);
 484 
 485 /** \brief Insert a PCI object in the given PCI tree by looking at PCI bus IDs.
 486  *
 487  * If \p treep points to \c NULL, the new object is inserted there.
 488  */
 489 HWLOC_DECLSPEC void hwloc_pcidisc_tree_insert_by_busid(struct hwloc_obj **treep, struct hwloc_obj *obj);
 490 
 491 /** \brief Add some hostbridges on top of the given tree of PCI objects and attach them to the topology.
 492  *
 493  * For now, they will be attached to the root object. The core will move them to their actual PCI
 494  * locality using hwloc_pci_belowroot_apply_locality() at the end of the discovery.
 495  *
 496  * In the meantime, other backends lookup PCI objects or localities (for instance to attach OS devices)
 497  * by using hwloc_pcidisc_find_by_busid() or hwloc_pcidisc_find_busid_parent().
 498  */
 499 HWLOC_DECLSPEC int hwloc_pcidisc_tree_attach(struct hwloc_topology *topology, struct hwloc_obj *tree);
 500 
 501 /** @} */
 502 
 503 
 504 
 505 
 506 /** \defgroup hwlocality_components_pcifind Components and Plugins: finding PCI objects during other discoveries
 507  * @{
 508  */
 509 
 510 /** \brief Find the PCI object that matches the bus ID.
 511  *
 512  * To be used after a PCI backend added PCI devices with hwloc_pcidisc_tree_attach()
 513  * and before the core moves them to their actual location with hwloc_pci_belowroot_apply_locality().
 514  *
 515  * If no exactly matching object is found, return the container bridge if any, or NULL.
 516  *
 517  * On failure, it may be possible to find the PCI locality (instead of the PCI device)
 518  * by calling hwloc_pcidisc_find_busid_parent().
 519  *
 520  * \note This is semantically identical to hwloc_get_pcidev_by_busid() which only works
 521  * after the topology is fully loaded.
 522  */
 523 HWLOC_DECLSPEC struct hwloc_obj * hwloc_pcidisc_find_by_busid(struct hwloc_topology *topology, unsigned domain, unsigned bus, unsigned dev, unsigned func);
 524 
 525 /** \brief Find the normal parent of a PCI bus ID.
 526  *
 527  * Look at PCI affinity to find out where the given PCI bus ID should be attached.
 528  *
 529  * This function should be used to attach an I/O device directly under a normal
 530  * (non-I/O) object, instead of below a PCI object.
 531  * It is usually used by backends when hwloc_pcidisc_find_by_busid() failed
 532  * to find the hwloc object corresponding to this bus ID, for instance because
 533  * PCI discovery is not supported on this platform.
 534  */
 535 HWLOC_DECLSPEC struct hwloc_obj * hwloc_pcidisc_find_busid_parent(struct hwloc_topology *topology, unsigned domain, unsigned bus, unsigned dev, unsigned func);
 536 
 537 /** @} */
 538 
 539 
 540 
 541 
 542 #endif /* HWLOC_PLUGINS_H */

/* [<][>][^][v][top][bottom][index][help] */