Skip to content

Commit 015b20a

Browse files
committed
osdev: change osdev.type from an enum to a bitmask
Each value is now 1<<x instead of x, and some got reordered. No multiple bits set yet. Default/unknown value is 0UL instead of -1. Signed-off-by: Brice Goglin <[email protected]>
1 parent a696220 commit 015b20a

26 files changed

+287
-225
lines changed

NEWS

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ Version 3.0.0
3030
+ PCI domains are now always 32bits.
3131
+ The "programming interface" of PCI devices is now exposed
3232
in PCI object attributes.
33-
+ "Block" OS devices are now "Storage" (for actual Block devices)
34-
or "Memory" (for Linux DAX and CXL devices, etc).
33+
+ The OS device "type" attribute is now a bitmask.
34+
- "Block" OS devices are now "Storage" (for actual Block devices)
35+
or "Memory" (for Linux DAX and CXL devices, etc).
3536
+ The "Backend" info attribute of OS devices is now in the topology
3637
root object together with other backends.
3738
+ The array and count of info attributes are now embedded in the new

hwloc/topology-xml.c

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -384,13 +384,14 @@ hwloc__xml_import_object_attr(struct hwloc_topology *topology,
384384
else if (!strcmp(name, "osdev_type")) {
385385
switch (obj->type) {
386386
case HWLOC_OBJ_OS_DEVICE: {
387-
unsigned osdev_type;
388-
if (sscanf(value, "%u", &osdev_type) != 1) {
387+
unsigned long osdev_type;
388+
if (sscanf(value, "%lu", &osdev_type) != 1) {
389389
if (hwloc__xml_verbose())
390390
fprintf(stderr, "%s: ignoring invalid osdev_type format string %s\n",
391391
state->global->msgprefix, value);
392-
} else
393-
obj->attr->osdev.type = (hwloc_obj_osdev_type_t) osdev_type;
392+
} else {
393+
obj->attr->osdev.type = osdev_type; /* v2 types will be updated later in hwloc__xml_import_object() */
394+
}
394395
break;
395396
}
396397
default:
@@ -844,10 +845,34 @@ hwloc__xml_import_object(hwloc_topology_t topology,
844845
}
845846

846847
if (data->version_major < 3 && obj->type == HWLOC_OBJ_OS_DEVICE) {
847-
if (obj->attr->osdev.type == HWLOC_OBJ_OSDEV_STORAGE
848-
&& ((obj->name && !strncmp(obj->name, "dax", 3))
849-
|| (obj->subtype && !strcmp(obj->subtype, "CXLMem"))))
850-
obj->attr->osdev.type = HWLOC_OBJ_OSDEV_MEMORY;
848+
unsigned long oldtype = obj->attr->osdev.type;
849+
switch (oldtype) {
850+
case 0: /* v2 Block */
851+
obj->attr->osdev.type = HWLOC_OBJ_OSDEV_STORAGE;
852+
if ((obj->name && !strncmp(obj->name, "dax", 3))
853+
|| (obj->subtype && !strcmp(obj->subtype, "CXLMem")))
854+
obj->attr->osdev.type = HWLOC_OBJ_OSDEV_MEMORY;
855+
break;
856+
case 1: /* v2 GPU */
857+
obj->attr->osdev.type = HWLOC_OBJ_OSDEV_GPU;
858+
break;
859+
case 2: /* v2 Net */
860+
obj->attr->osdev.type = HWLOC_OBJ_OSDEV_NETWORK;
861+
break;
862+
case 3: /* v2 OFED */
863+
obj->attr->osdev.type = HWLOC_OBJ_OSDEV_OPENFABRICS;
864+
break;
865+
case 4: /* v2 DMA */
866+
obj->attr->osdev.type = HWLOC_OBJ_OSDEV_DMA;
867+
break;
868+
case 5: /* v2 COPROC */
869+
obj->attr->osdev.type = HWLOC_OBJ_OSDEV_COPROC;
870+
break;
871+
default:
872+
/* unrecognized, no type */
873+
obj->attr->osdev.type = 0;
874+
break;
875+
}
851876
}
852877

853878
/* filter AFTER having updated the osdevice attribute from v2 */
@@ -2216,11 +2241,24 @@ hwloc__xml_export_object_contents (hwloc__xml_export_state_t state, hwloc_topolo
22162241
state->new_prop(state, "pci_link_speed", tmp);
22172242
break;
22182243
case HWLOC_OBJ_OS_DEVICE:
2219-
if (v2export && obj->attr->osdev.type == HWLOC_OBJ_OSDEV_MEMORY)
2220-
sprintf(tmp, "%d", (int) HWLOC_OBJ_OSDEV_STORAGE);
2221-
else
2222-
sprintf(tmp, "%d", (int) obj->attr->osdev.type);
2223-
state->new_prop(state, "osdev_type", tmp);
2244+
if (v2export) {
2245+
if (obj->attr->osdev.type & (HWLOC_OBJ_OSDEV_STORAGE|HWLOC_OBJ_OSDEV_MEMORY)) {
2246+
state->new_prop(state, "osdev_type", "0"); /* v2 Block */
2247+
} else if (obj->attr->osdev.type == HWLOC_OBJ_OSDEV_OPENFABRICS) {
2248+
state->new_prop(state, "osdev_type", "3"); /* v2 OFED */
2249+
} else if (obj->attr->osdev.type == HWLOC_OBJ_OSDEV_NETWORK) {
2250+
state->new_prop(state, "osdev_type", "2"); /* v2 Net */
2251+
} else if (obj->attr->osdev.type == HWLOC_OBJ_OSDEV_DMA) {
2252+
state->new_prop(state, "osdev_type", "4"); /* v2 DMA */
2253+
} else if (obj->attr->osdev.type == HWLOC_OBJ_OSDEV_COPROC) {
2254+
state->new_prop(state, "osdev_type", "5"); /* v2 CoProc */
2255+
} else if (obj->attr->osdev.type == HWLOC_OBJ_OSDEV_GPU) {
2256+
state->new_prop(state, "osdev_type", "1"); /* v2 GPU */
2257+
}
2258+
} else {
2259+
sprintf(tmp, "%lu", obj->attr->osdev.type);
2260+
state->new_prop(state, "osdev_type", tmp);
2261+
}
22242262
break;
22252263
default:
22262264
break;

hwloc/traversal.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ hwloc_type_sscanf(const char *string, hwloc_obj_type_t *typep,
366366
unsigned depthattr = (unsigned) -1;
367367
hwloc_obj_cache_type_t cachetypeattr = (hwloc_obj_cache_type_t) -1; /* unspecified */
368368
hwloc_obj_bridge_type_t ubtype = (hwloc_obj_bridge_type_t) -1;
369-
hwloc_obj_osdev_type_t ostype = (hwloc_obj_osdev_type_t) -1;
369+
hwloc_obj_osdev_type_t ostype = 0; /* none */
370370
char *end;
371371

372372
/* Never match the ending \0 since we want to match things like core:2 too.
@@ -378,10 +378,12 @@ hwloc_type_sscanf(const char *string, hwloc_obj_type_t *typep,
378378
if (!hwloc_strncasecmp(string, "osdev[", 6)) {
379379
/* proper "OSDev[type]" */
380380
type = HWLOC_OBJ_OS_DEVICE;
381+
ostype = 0;
381382
hwloc__osdev_type_sscanf(string+6, &ostype);
382383
} else if (!hwloc_strncasecmp(string, "os[", 3)) {
383384
/* shorter "OS[type]" */
384385
type = HWLOC_OBJ_OS_DEVICE;
386+
ostype = 0;
385387
hwloc__osdev_type_sscanf(string+3, &ostype);
386388
} else if (hwloc__type_match(string, "osdev", 2)) {
387389
/* basic "OSDev" without type */

include/hwloc.h

Lines changed: 45 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -356,28 +356,48 @@ typedef enum hwloc_obj_bridge_type_e {
356356
HWLOC_OBJ_BRIDGE_PCI /**< \brief PCI-side of a bridge. */
357357
} hwloc_obj_bridge_type_t;
358358

359-
/** \brief Type of a OS device. */
360-
typedef enum hwloc_obj_osdev_type_e {
361-
HWLOC_OBJ_OSDEV_STORAGE, /**< \brief Operating system storage device (e.g. block),
362-
* For instance "sda" on Linux. */
363-
HWLOC_OBJ_OSDEV_GPU, /**< \brief Operating system GPU device.
364-
* For instance ":0.0" for a GL display,
365-
* "card0" for a Linux DRM device. */
366-
HWLOC_OBJ_OSDEV_NETWORK, /**< \brief Operating system network device.
367-
* For instance the "eth0" interface on Linux. */
368-
HWLOC_OBJ_OSDEV_OPENFABRICS, /**< \brief Operating system openfabrics device.
369-
* For instance the "mlx4_0" InfiniBand HCA,
370-
* "hfi1_0" Omni-Path interface,
371-
* or "bxi0" Atos/Bull BXI HCA on Linux. */
372-
HWLOC_OBJ_OSDEV_DMA, /**< \brief Operating system dma engine device.
373-
* For instance the "dma0chan0" DMA channel on Linux. */
374-
HWLOC_OBJ_OSDEV_COPROC, /**< \brief Operating system co-processor device.
375-
* For instance "opencl0d0" for a OpenCL device,
376-
* "cuda0" for a CUDA device. */
377-
HWLOC_OBJ_OSDEV_MEMORY /**< \brief Operating system memory device
378-
* (e.g. DAX file for non-volatile or high-bandwidth memory),
379-
* For instance "dax2.0" on Linux. */
380-
} hwloc_obj_osdev_type_t;
359+
/** \brief Single type of a OS device.
360+
* Multiple of these may be combined for a single device.
361+
*/
362+
enum hwloc_obj_osdev_type_e {
363+
HWLOC_OBJ_OSDEV_STORAGE = (1ULL<<0), /**< \brief Operating system storage device (e.g. block).
364+
* For instance "sda" on Linux.
365+
* \hideinitializer
366+
*/
367+
HWLOC_OBJ_OSDEV_MEMORY = (1ULL<<1), /**< \brief Operating system memory device.
368+
(e.g. DAX file for non-volatile or high-bandwidth memory).
369+
* For instance "dax2.0" on Linux.
370+
* \hideinitializer
371+
*/
372+
HWLOC_OBJ_OSDEV_GPU = (1ULL<<2), /**< \brief Operating system GPU device.
373+
* For instance ":0.0" for a GL display,
374+
* "card0" for a Linux DRM device.
375+
* \hideinitializer
376+
*/
377+
HWLOC_OBJ_OSDEV_COPROC = (1ULL<<3), /**< \brief Operating system co-processor device.
378+
* For instance "opencl0d0" for a OpenCL device,
379+
* "cuda0", "ze0.0" for driver-specific GPU handles.
380+
* \hideinitializer
381+
*/
382+
HWLOC_OBJ_OSDEV_NETWORK = (1ULL<<4), /**< \brief Operating system network device.
383+
* For instance the "eth0" interface on Linux.
384+
* \hideinitializer
385+
*/
386+
HWLOC_OBJ_OSDEV_OPENFABRICS = (1ULL<<5), /**< \brief Operating system OpenFabrics device.
387+
* For instance the "mlx4_0" InfiniBand HCA,
388+
* or "hfi1_0" Omni-Path interface.
389+
* \hideinitializer
390+
*/
391+
HWLOC_OBJ_OSDEV_DMA = (1ULL<<6) /**< \brief Operating system dma engine device.
392+
* For instance the "dma0chan0" DMA channel on Linux.
393+
* \hideinitializer
394+
*/
395+
};
396+
397+
/** \brief Type of a OS device.
398+
* OR'ed set of ::hwloc_obj_osdev_type_e.
399+
*/
400+
typedef unsigned long hwloc_obj_osdev_type_t;
381401

382402
/** \brief Compare the depth of two object types
383403
*
@@ -703,7 +723,7 @@ union hwloc_obj_attr_u {
703723
} bridge;
704724
/** \brief OS Device specific Object Attributes */
705725
struct hwloc_osdev_attr_s {
706-
hwloc_obj_osdev_type_t type;
726+
hwloc_obj_osdev_type_t type; /**< \brief OR'ed set of at least one ::hwloc_obj_osdev_type_e. */
707727
} osdev;
708728
};
709729

@@ -1124,7 +1144,8 @@ enum hwloc_obj_snprintf_flag_e {
11241144
* Type-specific attributes, for instance Cache type, Cache depth, Group depth,
11251145
* Bridge type or OS Device type may be returned in \p attrp.
11261146
* Attributes that are not specified in the string (for instance "Group"
1127-
* without a depth, or "L2Cache" without a cache type) are set to -1.
1147+
* without a depth, or "L2Cache" without a cache type) are set to \c -1.
1148+
* The OS-device-specific type attribute is rather set to \c 0.
11281149
*
11291150
* \p attrp is only filled if not \c NULL and if its size specified in \p attrsize
11301151
* is large enough. It should be at least as large as union hwloc_obj_attr_u.

tests/hwloc/hwloc_iodevs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Copyright © 2009 CNRS
3-
* Copyright © 2009-2019 Inria. All rights reserved.
3+
* Copyright © 2009-2023 Inria. All rights reserved.
44
* Copyright © Université Bordeaux
55
* See COPYING in top-level directory.
66
*/
@@ -56,7 +56,7 @@ int main(void)
5656
obj = NULL;
5757
while ((obj = hwloc_get_next_osdev(topology, obj)) != NULL) {
5858
assert(obj->type == HWLOC_OBJ_OS_DEVICE);
59-
printf(" Found OS device %s subtype %d\n", obj->name, (int) obj->attr->osdev.type);
59+
printf(" Found OS device %s subtype %lu\n", obj->name, (unsigned long) obj->attr->osdev.type);
6060
}
6161

6262
assert(HWLOC_TYPE_DEPTH_BRIDGE == hwloc_get_type_depth(topology, HWLOC_OBJ_BRIDGE));

tests/hwloc/hwloc_type_sscanf.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -110,35 +110,35 @@ int main(void)
110110
err = hwloc_type_sscanf("osdev", &type, &attr, sizeof(attr));
111111
assert(!err);
112112
assert(type == HWLOC_OBJ_OS_DEVICE);
113-
assert(attr.osdev.type == (hwloc_obj_osdev_type_t) -1);
113+
assert(attr.osdev.type == 0);
114114
err = hwloc_type_sscanf("osdev0", &type, &attr, sizeof(attr));
115115
assert(!err);
116116
assert(type == HWLOC_OBJ_OS_DEVICE);
117-
assert(attr.osdev.type == (hwloc_obj_osdev_type_t) -1);
117+
assert(attr.osdev.type == 0);
118118
err = hwloc_type_sscanf("osdev:", &type, &attr, sizeof(attr));
119119
assert(!err);
120120
assert(type == HWLOC_OBJ_OS_DEVICE);
121-
assert(attr.osdev.type == (hwloc_obj_osdev_type_t) -1);
121+
assert(attr.osdev.type == 0);
122122
err = hwloc_type_sscanf("osde_", &type, &attr, sizeof(attr));
123123
assert(!err);
124124
assert(type == HWLOC_OBJ_OS_DEVICE);
125-
assert(attr.osdev.type == (hwloc_obj_osdev_type_t) -1);
125+
assert(attr.osdev.type == 0);
126126
err = hwloc_type_sscanf("osD[", &type, &attr, sizeof(attr));
127127
assert(!err);
128128
assert(type == HWLOC_OBJ_OS_DEVICE);
129-
assert(attr.osdev.type == (hwloc_obj_osdev_type_t) -1);
129+
assert(attr.osdev.type == 0);
130130
err = hwloc_type_sscanf("os(", &type, &attr, sizeof(attr));
131131
assert(!err);
132132
assert(type == HWLOC_OBJ_OS_DEVICE);
133-
assert(attr.osdev.type == (hwloc_obj_osdev_type_t) -1);
133+
assert(attr.osdev.type == 0);
134134
err = hwloc_type_sscanf("os[foo]", &type, &attr, sizeof(attr));
135135
assert(!err);
136136
assert(type == HWLOC_OBJ_OS_DEVICE);
137-
assert(attr.osdev.type == (hwloc_obj_osdev_type_t) -1);
137+
assert(attr.osdev.type == 0);
138138
err = hwloc_type_sscanf("osdev[]", &type, &attr, sizeof(attr));
139139
assert(!err);
140140
assert(type == HWLOC_OBJ_OS_DEVICE);
141-
assert(attr.osdev.type == (hwloc_obj_osdev_type_t) -1);
141+
assert(attr.osdev.type == 0);
142142
err = hwloc_type_sscanf("os[gpu]", &type, &attr, sizeof(attr));
143143
assert(!err);
144144
assert(type == HWLOC_OBJ_OS_DEVICE);

0 commit comments

Comments
 (0)