]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - tools/perf/util/header.c
perf tools: Add perf_exe() helper to find perf binary
[linux.git] / tools / perf / util / header.c
index dec6d218c31c326ceac4d4464c8c9ce012a1be61..01b324c275b9d1ba0bd771f30b49952550038295 100644 (file)
@@ -39,6 +39,7 @@
 #include "tool.h"
 #include "time-utils.h"
 #include "units.h"
+#include "cputopo.h"
 
 #include "sane_ctype.h"
 
@@ -526,17 +527,11 @@ static int write_event_desc(struct feat_fd *ff,
 static int write_cmdline(struct feat_fd *ff,
                         struct perf_evlist *evlist __maybe_unused)
 {
-       char buf[MAXPATHLEN];
-       u32 n;
-       int i, ret;
+       char pbuf[MAXPATHLEN], *buf;
+       int i, ret, n;
 
        /* actual path to perf binary */
-       ret = readlink("/proc/self/exe", buf, sizeof(buf) - 1);
-       if (ret <= 0)
-               return -1;
-
-       /* readlink() does not add null termination */
-       buf[ret] = '\0';
+       buf = perf_exe(pbuf, MAXPATHLEN);
 
        /* account for binary path */
        n = perf_env.nr_cmdline + 1;
@@ -557,160 +552,15 @@ static int write_cmdline(struct feat_fd *ff,
        return 0;
 }
 
-#define CORE_SIB_FMT \
-       "/sys/devices/system/cpu/cpu%d/topology/core_siblings_list"
-#define THRD_SIB_FMT \
-       "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list"
-
-struct cpu_topo {
-       u32 cpu_nr;
-       u32 core_sib;
-       u32 thread_sib;
-       char **core_siblings;
-       char **thread_siblings;
-};
-
-static int build_cpu_topo(struct cpu_topo *tp, int cpu)
-{
-       FILE *fp;
-       char filename[MAXPATHLEN];
-       char *buf = NULL, *p;
-       size_t len = 0;
-       ssize_t sret;
-       u32 i = 0;
-       int ret = -1;
-
-       sprintf(filename, CORE_SIB_FMT, cpu);
-       fp = fopen(filename, "r");
-       if (!fp)
-               goto try_threads;
-
-       sret = getline(&buf, &len, fp);
-       fclose(fp);
-       if (sret <= 0)
-               goto try_threads;
-
-       p = strchr(buf, '\n');
-       if (p)
-               *p = '\0';
-
-       for (i = 0; i < tp->core_sib; i++) {
-               if (!strcmp(buf, tp->core_siblings[i]))
-                       break;
-       }
-       if (i == tp->core_sib) {
-               tp->core_siblings[i] = buf;
-               tp->core_sib++;
-               buf = NULL;
-               len = 0;
-       }
-       ret = 0;
-
-try_threads:
-       sprintf(filename, THRD_SIB_FMT, cpu);
-       fp = fopen(filename, "r");
-       if (!fp)
-               goto done;
-
-       if (getline(&buf, &len, fp) <= 0)
-               goto done;
-
-       p = strchr(buf, '\n');
-       if (p)
-               *p = '\0';
-
-       for (i = 0; i < tp->thread_sib; i++) {
-               if (!strcmp(buf, tp->thread_siblings[i]))
-                       break;
-       }
-       if (i == tp->thread_sib) {
-               tp->thread_siblings[i] = buf;
-               tp->thread_sib++;
-               buf = NULL;
-       }
-       ret = 0;
-done:
-       if(fp)
-               fclose(fp);
-       free(buf);
-       return ret;
-}
-
-static void free_cpu_topo(struct cpu_topo *tp)
-{
-       u32 i;
-
-       if (!tp)
-               return;
-
-       for (i = 0 ; i < tp->core_sib; i++)
-               zfree(&tp->core_siblings[i]);
-
-       for (i = 0 ; i < tp->thread_sib; i++)
-               zfree(&tp->thread_siblings[i]);
-
-       free(tp);
-}
-
-static struct cpu_topo *build_cpu_topology(void)
-{
-       struct cpu_topo *tp = NULL;
-       void *addr;
-       u32 nr, i;
-       size_t sz;
-       long ncpus;
-       int ret = -1;
-       struct cpu_map *map;
-
-       ncpus = cpu__max_present_cpu();
-
-       /* build online CPU map */
-       map = cpu_map__new(NULL);
-       if (map == NULL) {
-               pr_debug("failed to get system cpumap\n");
-               return NULL;
-       }
-
-       nr = (u32)(ncpus & UINT_MAX);
-
-       sz = nr * sizeof(char *);
-       addr = calloc(1, sizeof(*tp) + 2 * sz);
-       if (!addr)
-               goto out_free;
-
-       tp = addr;
-       tp->cpu_nr = nr;
-       addr += sizeof(*tp);
-       tp->core_siblings = addr;
-       addr += sz;
-       tp->thread_siblings = addr;
-
-       for (i = 0; i < nr; i++) {
-               if (!cpu_map__has(map, i))
-                       continue;
-
-               ret = build_cpu_topo(tp, i);
-               if (ret < 0)
-                       break;
-       }
-
-out_free:
-       cpu_map__put(map);
-       if (ret) {
-               free_cpu_topo(tp);
-               tp = NULL;
-       }
-       return tp;
-}
 
 static int write_cpu_topology(struct feat_fd *ff,
                              struct perf_evlist *evlist __maybe_unused)
 {
-       struct cpu_topo *tp;
+       struct cpu_topology *tp;
        u32 i;
        int ret, j;
 
-       tp = build_cpu_topology();
+       tp = cpu_topology__new();
        if (!tp)
                return -1;
 
@@ -748,7 +598,7 @@ static int write_cpu_topology(struct feat_fd *ff,
                        return ret;
        }
 done:
-       free_cpu_topo(tp);
+       cpu_topology__delete(tp);
        return ret;
 }
 
@@ -783,112 +633,45 @@ static int write_total_mem(struct feat_fd *ff,
        return ret;
 }
 
-static int write_topo_node(struct feat_fd *ff, int node)
-{
-       char str[MAXPATHLEN];
-       char field[32];
-       char *buf = NULL, *p;
-       size_t len = 0;
-       FILE *fp;
-       u64 mem_total, mem_free, mem;
-       int ret = -1;
-
-       sprintf(str, "/sys/devices/system/node/node%d/meminfo", node);
-       fp = fopen(str, "r");
-       if (!fp)
-               return -1;
-
-       while (getline(&buf, &len, fp) > 0) {
-               /* skip over invalid lines */
-               if (!strchr(buf, ':'))
-                       continue;
-               if (sscanf(buf, "%*s %*d %31s %"PRIu64, field, &mem) != 2)
-                       goto done;
-               if (!strcmp(field, "MemTotal:"))
-                       mem_total = mem;
-               if (!strcmp(field, "MemFree:"))
-                       mem_free = mem;
-       }
-
-       fclose(fp);
-       fp = NULL;
-
-       ret = do_write(ff, &mem_total, sizeof(u64));
-       if (ret)
-               goto done;
-
-       ret = do_write(ff, &mem_free, sizeof(u64));
-       if (ret)
-               goto done;
-
-       ret = -1;
-       sprintf(str, "/sys/devices/system/node/node%d/cpulist", node);
-
-       fp = fopen(str, "r");
-       if (!fp)
-               goto done;
-
-       if (getline(&buf, &len, fp) <= 0)
-               goto done;
-
-       p = strchr(buf, '\n');
-       if (p)
-               *p = '\0';
-
-       ret = do_write_string(ff, buf);
-done:
-       free(buf);
-       if (fp)
-               fclose(fp);
-       return ret;
-}
-
 static int write_numa_topology(struct feat_fd *ff,
                               struct perf_evlist *evlist __maybe_unused)
 {
-       char *buf = NULL;
-       size_t len = 0;
-       FILE *fp;
-       struct cpu_map *node_map = NULL;
-       char *c;
-       u32 nr, i, j;
+       struct numa_topology *tp;
        int ret = -1;
+       u32 i;
 
-       fp = fopen("/sys/devices/system/node/online", "r");
-       if (!fp)
-               return -1;
-
-       if (getline(&buf, &len, fp) <= 0)
-               goto done;
+       tp = numa_topology__new();
+       if (!tp)
+               return -ENOMEM;
 
-       c = strchr(buf, '\n');
-       if (c)
-               *c = '\0';
+       ret = do_write(ff, &tp->nr, sizeof(u32));
+       if (ret < 0)
+               goto err;
 
-       node_map = cpu_map__new(buf);
-       if (!node_map)
-               goto done;
+       for (i = 0; i < tp->nr; i++) {
+               struct numa_topology_node *n = &tp->nodes[i];
 
-       nr = (u32)node_map->nr;
+               ret = do_write(ff, &n->node, sizeof(u32));
+               if (ret < 0)
+                       goto err;
 
-       ret = do_write(ff, &nr, sizeof(nr));
-       if (ret < 0)
-               goto done;
+               ret = do_write(ff, &n->mem_total, sizeof(u64));
+               if (ret)
+                       goto err;
 
-       for (i = 0; i < nr; i++) {
-               j = (u32)node_map->map[i];
-               ret = do_write(ff, &j, sizeof(j));
-               if (ret < 0)
-                       break;
+               ret = do_write(ff, &n->mem_free, sizeof(u64));
+               if (ret)
+                       goto err;
 
-               ret = write_topo_node(ff, i);
+               ret = do_write_string(ff, n->cpus);
                if (ret < 0)
-                       break;
+                       goto err;
        }
-done:
-       free(buf);
-       fclose(fp);
-       cpu_map__put(node_map);
+
+       ret = 0;
+
+err:
+       numa_topology__delete(tp);
        return ret;
 }
 
@@ -1042,11 +825,9 @@ static int write_cpuid(struct feat_fd *ff,
        int ret;
 
        ret = get_cpuid(buffer, sizeof(buffer));
-       if (!ret)
-               goto write_it;
+       if (ret)
+               return -1;
 
-       return -1;
-write_it:
        return do_write_string(ff, buffer);
 }