perf path: Make mkpath thread safe, remove 16384 bytes from .bss
authorIan Rogers <irogers@google.com>
Fri, 26 May 2023 18:33:57 +0000 (11:33 -0700)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Sun, 28 May 2023 13:24:14 +0000 (10:24 -0300)
Avoid 4 static arrays for paths, pass in a char[] buffer to use. Makes
mkpath thread safe for the small number of users. Also removes 16,384
bytes from .bss.

Signed-off-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: K Prateek Nayak <kprateek.nayak@amd.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Ross Zwisler <zwisler@chromium.org>
Cc: Sean Christopherson <seanjc@google.com>
Cc: Steven Rostedt (VMware) <rostedt@goodmis.org>
Cc: Tiezhu Yang <yangtiezhu@loongson.cn>
Cc: Yang Jihong <yangjihong1@huawei.com>
Link: https://lore.kernel.org/r/20230526183401.2326121-13-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/builtin-config.c
tools/perf/builtin-help.c
tools/perf/util/cache.h
tools/perf/util/config.c
tools/perf/util/path.c

index 2603015f98becda774e3e9e672cf60ffc043332b..2e8363778935e8d576a4ddac7798020a3fbe3887 100644 (file)
@@ -12,6 +12,7 @@
 #include "util/debug.h"
 #include "util/config.h"
 #include <linux/string.h>
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 
@@ -157,7 +158,8 @@ int cmd_config(int argc, const char **argv)
 {
        int i, ret = -1;
        struct perf_config_set *set;
-       char *user_config = mkpath("%s/.perfconfig", getenv("HOME"));
+       char path[PATH_MAX];
+       char *user_config = mkpath(path, sizeof(path), "%s/.perfconfig", getenv("HOME"));
        const char *config_filename;
        bool changed = false;
 
index 3e7f52054fac0339e735a43ff0b0d05c8ce5fecd..b2a368ae295a1ecef1ae7c504784981a7df46003 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/string.h>
 #include <linux/zalloc.h>
 #include <errno.h>
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -389,9 +390,10 @@ static int get_html_page_path(char **page_path, const char *page)
 {
        struct stat st;
        const char *html_path = system_path(PERF_HTML_PATH);
+       char path[PATH_MAX];
 
        /* Check that we have a perf documentation directory. */
-       if (stat(mkpath("%s/perf.html", html_path), &st)
+       if (stat(mkpath(path, sizeof(path), "%s/perf.html", html_path), &st)
            || !S_ISREG(st.st_mode)) {
                pr_err("'%s': not a documentation directory.", html_path);
                return -1;
index 9f2e36ef5072e9e8a690cc53fe0c4bee5e6928db..0b61840d42267fcdea61745269fba3e5237dba9e 100644 (file)
@@ -26,6 +26,6 @@ static inline int is_absolute_path(const char *path)
        return path[0] == '/';
 }
 
-char *mkpath(const char *fmt, ...) __printf(1, 2);
+char *mkpath(char *path_buf, size_t sz, const char *fmt, ...) __printf(3, 4);
 
 #endif /* __PERF_CACHE_H */
index 658170b8dcef73ebeadf91c1f7cfd24a62f14b95..f340dc73db6ddcf18b49868bb6d8300c25eca83e 100644 (file)
@@ -543,6 +543,7 @@ static char *home_perfconfig(void)
        const char *home = NULL;
        char *config;
        struct stat st;
+       char path[PATH_MAX];
 
        home = getenv("HOME");
 
@@ -554,7 +555,7 @@ static char *home_perfconfig(void)
        if (!home || !*home || !perf_config_global())
                return NULL;
 
-       config = strdup(mkpath("%s/.perfconfig", home));
+       config = strdup(mkpath(path, sizeof(path), "%s/.perfconfig", home));
        if (config == NULL) {
                pr_warning("Not enough memory to process %s/.perfconfig, ignoring it.\n", home);
                return NULL;
index ce80b79be1036f9f0624c8230a3dee93bf60cfd4..00adf872bf00ba28c3b0b6f2ca6a6dd5fec3ffdb 100644 (file)
@@ -1,16 +1,4 @@
 // SPDX-License-Identifier: GPL-2.0
-/*
- * I'm tired of doing "vsnprintf()" etc just to open a
- * file, so here's a "return static buffer with printf"
- * interface for paths.
- *
- * It's obviously not thread-safe. Sue me. But it's quite
- * useful for doing things like
- *
- *   f = open(mkpath("%s/%s.perf", base, name), O_RDONLY);
- *
- * which is what it's designed for.
- */
 #include "path.h"
 #include "cache.h"
 #include <linux/kernel.h>
 #include <dirent.h>
 #include <unistd.h>
 
-static char bad_path[] = "/bad-path/";
-/*
- * One hack:
- */
-static char *get_pathname(void)
-{
-       static char pathname_array[4][PATH_MAX];
-       static int idx;
-
-       return pathname_array[3 & ++idx];
-}
-
 static char *cleanup_path(char *path)
 {
        /* Clean it up */
@@ -45,18 +21,17 @@ static char *cleanup_path(char *path)
        return path;
 }
 
-char *mkpath(const char *fmt, ...)
+char *mkpath(char *path_buf, size_t sz, const char *fmt, ...)
 {
        va_list args;
        unsigned len;
-       char *pathname = get_pathname();
 
        va_start(args, fmt);
-       len = vsnprintf(pathname, PATH_MAX, fmt, args);
+       len = vsnprintf(path_buf, sz, fmt, args);
        va_end(args);
-       if (len >= PATH_MAX)
-               return bad_path;
-       return cleanup_path(pathname);
+       if (len >= sz)
+               strncpy(path_buf, "/bad-path/", sz);
+       return cleanup_path(path_buf);
 }
 
 int path__join(char *bf, size_t size, const char *path1, const char *path2)