Skip to content

Commit 103f1fa

Browse files
committed
utils: move the parsing of os[] and pci[:] filters to hwloc_calc_parse_level()
Don't duplicate the parsing of osdev type, just use the now official parsing of strings like "os[net]". Remove a temporary hack that was needed for parsing pci[vendor:device] now that hwloc_calc_parse_level() takes care of it. Signed-off-by: Brice Goglin <[email protected]>
1 parent 323bdba commit 103f1fa

File tree

3 files changed

+81
-99
lines changed

3 files changed

+81
-99
lines changed

utils/hwloc/hwloc-annotate.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ get_unique_obj(hwloc_topology_t topology, int topodepth, char *str,
172172
int err;
173173

174174
typelen = hwloc_calc_parse_level_size(str);
175-
if (!typelen || (str[typelen] != ':' && str[typelen] != '=' && str[typelen] != '['))
175+
if (!typelen || (str[typelen] != ':' && str[typelen] != '='))
176176
return NULL;
177177

178178
lcontext.topology = topology;

utils/hwloc/hwloc-calc.h

Lines changed: 78 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ struct hwloc_calc_level {
3737
int depth;
3838
hwloc_obj_type_t type;
3939
union hwloc_obj_attr_u attr;
40+
int pci_vendor, pci_device;
4041
int only_hbm; /* -1 for everything, 0 for only non-HBM, 1 for only HBM numa nodes */
4142
};
4243

@@ -151,16 +152,69 @@ hwloc_calc_get_obj_inside_sets_by_depth(struct hwloc_calc_location_context_s *lc
151152
return NULL;
152153
}
153154

154-
/* return the length of the type/depth prefix
155+
/* return the length of the type/depth prefix (including filters if any)
155156
* 0 if not found or invalid.
156157
*/
157158
static __hwloc_inline size_t
158159
hwloc_calc_parse_level_size(const char *string)
159160
{
161+
size_t len;
162+
const char *filter_end;
163+
160164
/* type/depth prefix ends with either '.' (for child), "=" (for name of osdev),
161-
* ':' (for index).
165+
* ':' (for index), or '[' (for filters).
162166
*/
163-
return strcspn(string, ":=.");
167+
len = strcspn(string, ":=.[");
168+
if (string[len] != '[')
169+
return len;
170+
171+
/* we want to include filters */
172+
filter_end = strchr(string+len, ']');
173+
if (!filter_end)
174+
return 0;
175+
return filter_end + 1 - string;
176+
}
177+
178+
static __hwloc_inline int
179+
hwloc_calc_parse_level_filter(hwloc_topology_t topology __hwloc_attribute_unused,
180+
const char *filter,
181+
struct hwloc_calc_level *level)
182+
{
183+
const char *current = filter;
184+
185+
if (level->type == HWLOC_OBJ_PCI_DEVICE) {
186+
/* try to match by [vendor:device] */
187+
char *endp;
188+
189+
level->pci_vendor = strtoul(current, &endp, 16);
190+
if (*endp != ':') {
191+
fprintf(stderr, "invalid PCI vendor:device filter specification %s\n", filter);
192+
return -1;
193+
}
194+
if (endp == current)
195+
level->pci_vendor = -1;
196+
current = endp+1;
197+
198+
level->pci_device = strtoul(current, &endp, 16);
199+
if (*endp != ']') {
200+
fprintf(stderr, "invalid PCI vendor:device filter specification %s\n", filter);
201+
return -1;
202+
}
203+
if (endp == current)
204+
level->pci_device = -1;
205+
current = endp+1;
206+
207+
if (*current != ':' && *current != '\0') {
208+
fprintf(stderr, "invalid PCI vendor:device filter specification %s\n", filter);
209+
return -1;
210+
}
211+
212+
} else if (level->type != HWLOC_OBJ_OS_DEVICE) {
213+
fprintf(stderr, "invalid filter specification %s\n", filter);
214+
return -1;
215+
}
216+
217+
return 0;
164218
}
165219

166220
static __hwloc_inline int
@@ -173,6 +227,7 @@ hwloc_calc_parse_level(struct hwloc_calc_location_context_s *lcontext,
173227
char *endptr;
174228
int err;
175229

230+
level->pci_device = level->pci_vendor = -1;
176231
level->only_hbm = -1;
177232
if (lcontext)
178233
level->only_hbm = lcontext->only_hbm;
@@ -185,11 +240,19 @@ hwloc_calc_parse_level(struct hwloc_calc_location_context_s *lcontext,
185240

186241
err = hwloc_type_sscanf(typestring, &level->type, &level->attr, sizeof(level->attr));
187242
if (!err) {
243+
char *bracket;
188244
/* parsed a correct type */
189245
level->depth = hwloc_get_type_depth_with_attr(topology, level->type, &level->attr, sizeof(level->attr));
190246
if (level->depth == HWLOC_TYPE_DEPTH_UNKNOWN
191247
|| level->depth == HWLOC_TYPE_DEPTH_MULTIPLE)
192248
return -1;
249+
250+
bracket = strchr(typestring, '[');
251+
if (bracket) {
252+
err = hwloc_calc_parse_level_filter(topology, bracket+1, level);
253+
if (err < 0)
254+
return -1;
255+
}
193256
return 0;
194257
}
195258

@@ -421,91 +484,17 @@ hwloc_calc_append_iodev(struct hwloc_calc_location_context_s *lcontext,
421484

422485
static __hwloc_inline int
423486
hwloc_calc_append_iodev_by_index(struct hwloc_calc_location_context_s *lcontext,
424-
hwloc_obj_type_t type, int depth, const char *string,
487+
struct hwloc_calc_level *level, const char *string,
425488
void (*cbfunc)(struct hwloc_calc_location_context_s *, void *, hwloc_obj_t), void *cbdata)
426489
{
427490
hwloc_topology_t topology = lcontext->topology;
428491
int verbose = lcontext->verbose;
429492
hwloc_obj_t obj, prev = NULL;
430-
int pcivendor = -1, pcidevice = -1;
431-
hwloc_obj_osdev_type_t osdevtype = 0; /* none */
432493
const char *current, *dot;
433-
char *endp;
434494
int first = 0, step = 1, amount = 1, wrap = 0; /* assume the index suffix is `:0' by default */
435495
int err, i, max;
436496

437-
if (*string == '[') {
438-
/* matching */
439-
current = string+1;
440-
441-
if (type == HWLOC_OBJ_PCI_DEVICE) {
442-
/* try to match by [vendor:device] */
443-
pcivendor = strtoul(current, &endp, 16);
444-
if (*endp != ':') {
445-
if (verbose >= 0)
446-
fprintf(stderr, "invalid PCI vendor:device matching specification %s\n", string);
447-
return -1;
448-
}
449-
if (endp == current)
450-
pcivendor = -1;
451-
current = endp+1;
452-
453-
pcidevice = strtoul(current, &endp, 16);
454-
if (*endp != ']') {
455-
if (verbose >= 0)
456-
fprintf(stderr, "invalid PCI vendor:device matching specification %s\n", string);
457-
return -1;
458-
}
459-
if (endp == current)
460-
pcidevice = -1;
461-
current = endp+1;
462-
463-
if (*current != ':' && *current != '\0') {
464-
if (verbose >= 0)
465-
fprintf(stderr, "invalid PCI vendor:device matching specification %s\n", string);
466-
return -1;
467-
}
468-
469-
} else if (type == HWLOC_OBJ_OS_DEVICE) {
470-
/* try to match by [osdevtype] */
471-
hwloc_obj_type_t type2;
472-
union hwloc_obj_attr_u attr;
473-
474-
endp = strchr(current, ']');
475-
if (!endp) {
476-
if (verbose >= 0)
477-
fprintf(stderr, "invalid OS device subtype specification %s\n", string);
478-
return -1;
479-
}
480-
*endp = 0;
481-
482-
err = hwloc_type_sscanf(current, &type2, &attr, sizeof(attr));
483-
*endp = ']';
484-
if (err < 0 || type2 != HWLOC_OBJ_OS_DEVICE) {
485-
if (verbose >= 0)
486-
fprintf(stderr, "invalid OS device subtype specification %s\n", string);
487-
return -1;
488-
}
489-
osdevtype = attr.osdev.type;
490-
491-
current = endp+1;
492-
if (*current != ':' && *current != '\0') {
493-
if (verbose >= 0)
494-
fprintf(stderr, "invalid OS device subtype specification %s\n", string);
495-
return -1;
496-
}
497-
498-
} else {
499-
/* no matching for non-PCI devices */
500-
if (verbose >= 0)
501-
fprintf(stderr, "invalid matching specification %s\n", string);
502-
return -1;
503-
}
504-
505-
} else {
506-
/* no matching */
507-
current = string;
508-
}
497+
current = string;
509498

510499
if (*current != '\0') {
511500
current++;
@@ -524,29 +513,29 @@ hwloc_calc_append_iodev_by_index(struct hwloc_calc_location_context_s *lcontext,
524513
}
525514
}
526515

527-
max = hwloc_get_nbobjs_by_depth(topology, depth);
516+
max = hwloc_get_nbobjs_by_depth(topology, level->depth);
528517

529518
for(i=0; i < max*(wrap+1); i++) {
530519
if (i == max && wrap) {
531520
i = 0;
532521
wrap = 0;
533522
}
534523

535-
obj = hwloc_get_obj_by_depth(topology, depth, i);
524+
obj = hwloc_get_obj_by_depth(topology, level->depth, i);
536525
assert(obj);
537526

538527
if (obj == prev) /* already used that object, stop wrapping around */
539528
break;
540529

541-
if (type == HWLOC_OBJ_PCI_DEVICE) {
542-
if (pcivendor != -1 && (int) obj->attr->pcidev.vendor_id != pcivendor)
530+
if (level->type == HWLOC_OBJ_PCI_DEVICE) {
531+
if (level->pci_vendor != -1 && (int) obj->attr->pcidev.vendor_id != level->pci_vendor)
543532
continue;
544-
if (pcidevice != -1 && (int) obj->attr->pcidev.device_id != pcidevice)
533+
if (level->pci_device != -1 && (int) obj->attr->pcidev.device_id != level->pci_device)
545534
continue;
546535
}
547536

548-
if (type == HWLOC_OBJ_OS_DEVICE) {
549-
if ((obj->attr->osdev.type & osdevtype) != osdevtype)
537+
if (level->type == HWLOC_OBJ_OS_DEVICE) {
538+
if ((obj->attr->osdev.type & level->attr.osdev.type) != level->attr.osdev.type)
550539
continue;
551540
}
552541

@@ -603,16 +592,8 @@ hwloc_calc_process_location(struct hwloc_calc_location_context_s *lcontext,
603592
/* if we didn't find a depth but found a type, handle special cases */
604593
hwloc_obj_t obj = NULL;
605594

606-
if (*sep == ':' || *sep == '[') {
607-
if (level.type == HWLOC_OBJ_PCI_DEVICE) {
608-
/* FIXME: temporary hack because typelen includes pci and osdev filters
609-
* but only osdev types are handled in hwloc_calc_parse_level()
610-
*/
611-
const char *bracket = strchr(arg, '[');
612-
if (bracket && bracket-sep < 0)
613-
sep = bracket;
614-
}
615-
return hwloc_calc_append_iodev_by_index(lcontext, level.type, level.depth, sep, cbfunc, cbdata);
595+
if (*sep == ':') {
596+
return hwloc_calc_append_iodev_by_index(lcontext, &level, sep, cbfunc, cbdata);
616597

617598
} else if (*sep == '=' && level.type == HWLOC_OBJ_PCI_DEVICE) {
618599
/* try to match a busid */
@@ -717,7 +698,7 @@ hwloc_calc_process_location_as_set(struct hwloc_calc_location_context_s *lcontex
717698

718699
/* try to match a type/depth followed by a special character */
719700
typelen = hwloc_calc_parse_level_size(arg);
720-
if (typelen && (arg[typelen] == ':' || arg[typelen] == '=' || arg[typelen] == '[')) {
701+
if (typelen && (arg[typelen] == ':' || arg[typelen] == '=')) {
721702
/* process type/depth */
722703
struct hwloc_calc_process_location_set_cbdata_s cbdata;
723704
cbdata.set = hwloc_bitmap_alloc();

utils/hwloc/hwloc-info.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,7 @@ hwloc_calc_process_location_info_cb(struct hwloc_calc_location_context_s *lconte
535535
level.type = HWLOC_OBJ_TYPE_NONE;
536536
level.depth = show_descendants_depth;
537537
level.only_hbm = -1;
538+
level.pci_vendor = level.pci_device = -1;
538539
n = hwloc_calc_get_nbobjs_inside_sets_by_depth(lcontext, obj->cpuset, obj->nodeset, &level);
539540
for(i=0; i<n; i++) {
540541
hwloc_obj_t child = hwloc_calc_get_obj_inside_sets_by_depth(lcontext, obj->cpuset, obj->nodeset, &level, i);
@@ -1052,7 +1053,7 @@ main (int argc, char *argv[])
10521053
} else {
10531054
/* try to match a type/depth followed by a special character */
10541055
typelen = hwloc_calc_parse_level_size(argv[0]);
1055-
if (typelen && (argv[0][typelen] == ':' || argv[0][typelen] == '=' || argv[0][typelen] == '[')) {
1056+
if (typelen && (argv[0][typelen] == ':' || argv[0][typelen] == '=')) {
10561057
err = hwloc_calc_process_location(&lcontext, argv[0], typelen,
10571058
hwloc_calc_process_location_info_cb, NULL);
10581059
}

0 commit comments

Comments
 (0)