Skip to content

Commit d68c07e

Browse files
anakryikoAlexei Starovoitov
authored andcommitted
selftests/bpf: allow to define asc/desc ordering for sort specs in veristat
Allow to specify '^' at the end of stat name to designate that it should be sorted in ascending order. Similarly, allow any of 'v', 'V', '.', '!', or '_' suffix "symbols" to designate descending order. It's such a zoo for descending order because there is no single intuitive symbol that could be used (using 'v' looks pretty weird in practice), so few symbols that are "downwards leaning or pointing" were chosen. Either way, it shouldn't cause any troubles in practice. This new feature allows to customize sortering order to match user's needs. Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/r/20221103055304.2904589-6-andrii@kernel.org Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent b9670b9 commit d68c07e

1 file changed

Lines changed: 48 additions & 15 deletions

File tree

tools/testing/selftests/bpf/veristat.c

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -419,32 +419,65 @@ static struct stat_def {
419419
[MARK_READ_MAX_LEN] = { "Max mark read length", {"max_mark_read_len", "mark_read"}, },
420420
};
421421

422+
static bool parse_stat_id(const char *name, size_t len, int *id)
423+
{
424+
int i, j;
425+
426+
for (i = 0; i < ARRAY_SIZE(stat_defs); i++) {
427+
struct stat_def *def = &stat_defs[i];
428+
429+
for (j = 0; j < ARRAY_SIZE(stat_defs[i].names); j++) {
430+
431+
if (!def->names[j] ||
432+
strlen(def->names[j]) != len ||
433+
strncmp(def->names[j], name, len) != 0)
434+
continue;
435+
436+
*id = i;
437+
return true;
438+
}
439+
}
440+
441+
return false;
442+
}
443+
444+
static bool is_asc_sym(char c)
445+
{
446+
return c == '^';
447+
}
448+
449+
static bool is_desc_sym(char c)
450+
{
451+
return c == 'v' || c == 'V' || c == '.' || c == '!' || c == '_';
452+
}
453+
422454
static int parse_stat(const char *stat_name, struct stat_specs *specs)
423455
{
424-
int id, i;
456+
int id;
457+
bool has_order = false, is_asc = false;
458+
size_t len = strlen(stat_name);
425459

426460
if (specs->spec_cnt >= ARRAY_SIZE(specs->ids)) {
427461
fprintf(stderr, "Can't specify more than %zd stats\n", ARRAY_SIZE(specs->ids));
428462
return -E2BIG;
429463
}
430464

431-
for (id = 0; id < ARRAY_SIZE(stat_defs); id++) {
432-
struct stat_def *def = &stat_defs[id];
433-
434-
for (i = 0; i < ARRAY_SIZE(stat_defs[id].names); i++) {
435-
if (!def->names[i] || strcmp(def->names[i], stat_name) != 0)
436-
continue;
437-
438-
specs->ids[specs->spec_cnt] = id;
439-
specs->asc[specs->spec_cnt] = def->asc_by_default;
440-
specs->spec_cnt++;
465+
if (len > 1 && (is_asc_sym(stat_name[len - 1]) || is_desc_sym(stat_name[len - 1]))) {
466+
has_order = true;
467+
is_asc = is_asc_sym(stat_name[len - 1]);
468+
len -= 1;
469+
}
441470

442-
return 0;
443-
}
471+
if (!parse_stat_id(stat_name, len, &id)) {
472+
fprintf(stderr, "Unrecognized stat name '%s'\n", stat_name);
473+
return -ESRCH;
444474
}
445475

446-
fprintf(stderr, "Unrecognized stat name '%s'\n", stat_name);
447-
return -ESRCH;
476+
specs->ids[specs->spec_cnt] = id;
477+
specs->asc[specs->spec_cnt] = has_order ? is_asc : stat_defs[id].asc_by_default;
478+
specs->spec_cnt++;
479+
480+
return 0;
448481
}
449482

450483
static int parse_stats(const char *stats_str, struct stat_specs *specs)

0 commit comments

Comments
 (0)