summaryrefslogtreecommitdiffstats
path: root/tools/perf/util/help-unknown-cmd.c
diff options
context:
space:
mode:
authorYijie Yang <yijie.yang@oss.qualcomm.com>2026-08-11 16:46:47 +0800
committerRob Herring (Arm) <robh@kernel.org>2026-08-15 15:46:52 -0500
commite1c13aed4a1641550e8c9518c96f016e1d52d09b (patch)
tree61c2297688373db165cc857b7c7adcb147a5c419 /tools/perf/util/help-unknown-cmd.c
downloadlinux-stable-e1c13aed4a1641550e8c9518c96f016e1d52d09b.tar.gz
linux-stable-e1c13aed4a1641550e8c9518c96f016e1d52d09b.zip
dt-bindings: interconnect: qcom-bwmon: Add Maili cpu-bwmon compatiblegrafted
Add the Qualcomm Maili SoC compatible string for the CPU bandwidth monitor (BWMONv4). This falls back to the sdm845-bwmon compatible, consistent with the existing pattern used by other recent SoCs such as sm8750 and kaanapali. Signed-off-by: Yijie Yang <yijie.yang@oss.qualcomm.com> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com> Reviewed-by: Jingyi Wang <jingyi.wang@oss.qualcomm.com> Link: https://patch.msgid.link/20260811-bwmon-v2-1-80f7f150ab9e@oss.qualcomm.com Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
Diffstat (limited to 'tools/perf/util/help-unknown-cmd.c')
-rw-r--r--tools/perf/util/help-unknown-cmd.c122
1 files changed, 122 insertions, 0 deletions
diff --git a/tools/perf/util/help-unknown-cmd.c b/tools/perf/util/help-unknown-cmd.c
new file mode 100644
index 000000000..a0a46e34f
--- /dev/null
+++ b/tools/perf/util/help-unknown-cmd.c
@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "cache.h"
+#include "config.h"
+#include <poll.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <subcmd/help.h>
+#include "../builtin.h"
+#include "levenshtein.h"
+#include <linux/zalloc.h>
+
+static int autocorrect;
+
+static int perf_unknown_cmd_config(const char *var, const char *value,
+ void *cb __maybe_unused)
+{
+ if (!strcmp(var, "help.autocorrect"))
+ return perf_config_int(&autocorrect, var,value);
+
+ return 0;
+}
+
+static int levenshtein_compare(const void *p1, const void *p2)
+{
+ const struct cmdname *const *c1 = p1, *const *c2 = p2;
+ const char *s1 = (*c1)->name, *s2 = (*c2)->name;
+ int l1 = (*c1)->len;
+ int l2 = (*c2)->len;
+ return l1 != l2 ? l1 - l2 : strcmp(s1, s2);
+}
+
+static int add_cmd_list(struct cmdnames *cmds, struct cmdnames *old)
+{
+ unsigned int i, nr = cmds->cnt + old->cnt;
+ void *tmp;
+
+ if (nr > cmds->alloc) {
+ /* Choose bigger one to alloc */
+ if (alloc_nr(cmds->alloc) < nr)
+ cmds->alloc = nr;
+ else
+ cmds->alloc = alloc_nr(cmds->alloc);
+ tmp = realloc(cmds->names, cmds->alloc * sizeof(*cmds->names));
+ if (!tmp)
+ return -1;
+ cmds->names = tmp;
+ }
+ for (i = 0; i < old->cnt; i++)
+ cmds->names[cmds->cnt++] = old->names[i];
+ zfree(&old->names);
+ old->cnt = 0;
+ return 0;
+}
+
+const char *help_unknown_cmd(const char *cmd, struct cmdnames *main_cmds)
+{
+ unsigned int i, n = 0, best_similarity = 0;
+ struct cmdnames other_cmds;
+
+ memset(&other_cmds, 0, sizeof(other_cmds));
+
+ perf_config(perf_unknown_cmd_config, NULL);
+
+ load_command_list("perf-", main_cmds, &other_cmds);
+
+ if (add_cmd_list(main_cmds, &other_cmds) < 0) {
+ fprintf(stderr, "ERROR: Failed to allocate command list for unknown command.\n");
+ goto end;
+ }
+ qsort(main_cmds->names, main_cmds->cnt,
+ sizeof(main_cmds->names), cmdname_compare);
+ uniq(main_cmds);
+
+ if (main_cmds->cnt) {
+ /* This reuses cmdname->len for similarity index */
+ for (i = 0; i < main_cmds->cnt; ++i) {
+ main_cmds->names[i]->len =
+ levenshtein(cmd, main_cmds->names[i]->name,
+ /*swap_penalty=*/0,
+ /*substition_penality=*/2,
+ /*insertion_penality=*/1,
+ /*deletion_penalty=*/1);
+ }
+ qsort(main_cmds->names, main_cmds->cnt,
+ sizeof(*main_cmds->names), levenshtein_compare);
+
+ best_similarity = main_cmds->names[0]->len;
+ n = 1;
+ while (n < main_cmds->cnt && best_similarity == main_cmds->names[n]->len)
+ ++n;
+ }
+
+ if (autocorrect && n == 1) {
+ const char *assumed = main_cmds->names[0]->name;
+
+ main_cmds->names[0] = NULL;
+ clean_cmdnames(&other_cmds);
+ fprintf(stderr, "WARNING: You called a perf program named '%s', "
+ "which does not exist.\n"
+ "Continuing under the assumption that you meant '%s'\n",
+ cmd, assumed);
+ if (autocorrect > 0) {
+ fprintf(stderr, "in %0.1f seconds automatically...\n",
+ (float)autocorrect/10.0);
+ poll(NULL, 0, autocorrect * 100);
+ }
+ return assumed;
+ }
+
+ fprintf(stderr, "perf: '%s' is not a perf-command. See 'perf --help'.\n", cmd);
+
+ if (main_cmds->cnt && best_similarity < 6) {
+ fprintf(stderr, "\nDid you mean %s?\n",
+ n < 2 ? "this": "one of these");
+
+ for (i = 0; i < n; i++)
+ fprintf(stderr, "\t%s\n", main_cmds->names[i]->name);
+ }
+end:
+ clean_cmdnames(&other_cmds);
+ return NULL;
+}