Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf env: Introduce read_cpu_topology_map() method

Out of the code to write the cpu topology map in the perf.data file
header.

Now if one needs the CPU topology map for the running machine, one needs
to call perf_env__read_cpu_topology_map(perf_env) and the info will be
stored in perf_env.cpu.

For now we're using a global perf_env variable, that will have its
contents freed after we run a builtin.

v2: Check perf_env__read_cpu_topology_map() return in
write_cpu_topology() (Kan Liang)

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1441828225-667-5-git-send-email-acme@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

+44 -16
+2
tools/perf/perf.c
··· 8 8 */ 9 9 #include "builtin.h" 10 10 11 + #include "util/env.h" 11 12 #include "util/exec_cmd.h" 12 13 #include "util/cache.h" 13 14 #include "util/quote.h" ··· 370 369 371 370 status = p->fn(argc, argv, prefix); 372 371 exit_browser(status); 372 + perf_env__exit(&perf_env); 373 373 374 374 if (status) 375 375 return status & 0xff;
+28
tools/perf/util/env.c
··· 1 + #include "cpumap.h" 1 2 #include "env.h" 2 3 #include "util.h" 3 4 ··· 56 55 zfree(&env->cmdline_argv); 57 56 out_enomem: 58 57 return -ENOMEM; 58 + } 59 + 60 + int perf_env__read_cpu_topology_map(struct perf_env *env) 61 + { 62 + int cpu, nr_cpus; 63 + 64 + if (env->cpu != NULL) 65 + return 0; 66 + 67 + if (env->nr_cpus_avail == 0) 68 + env->nr_cpus_avail = sysconf(_SC_NPROCESSORS_CONF); 69 + 70 + nr_cpus = env->nr_cpus_avail; 71 + if (nr_cpus == -1) 72 + return -EINVAL; 73 + 74 + env->cpu = calloc(nr_cpus, sizeof(env->cpu[0])); 75 + if (env->cpu == NULL) 76 + return -ENOMEM; 77 + 78 + for (cpu = 0; cpu < nr_cpus; ++cpu) { 79 + env->cpu[cpu].core_id = cpu_map__get_core_id(cpu); 80 + env->cpu[cpu].socket_id = cpu_map__get_socket_id(cpu); 81 + } 82 + 83 + env->nr_cpus_avail = nr_cpus; 84 + return 0; 59 85 }
+2
tools/perf/util/env.h
··· 39 39 40 40 int perf_env__set_cmdline(struct perf_env *env, int argc, const char *argv[]); 41 41 42 + int perf_env__read_cpu_topology_map(struct perf_env *env); 43 + 42 44 #endif /* __PERF_ENV_H */
+12 -16
tools/perf/util/header.c
··· 415 415 u32 thread_sib; 416 416 char **core_siblings; 417 417 char **thread_siblings; 418 - int *core_id; 419 - int *phy_pkg_id; 420 418 }; 421 419 422 420 static int build_cpu_topo(struct cpu_topo *tp, int cpu) ··· 477 479 } 478 480 ret = 0; 479 481 done: 480 - tp->core_id[cpu] = cpu_map__get_core_id(cpu); 481 - tp->phy_pkg_id[cpu] = cpu_map__get_socket_id(cpu); 482 - 483 482 if(fp) 484 483 fclose(fp); 485 484 free(buf); ··· 504 509 struct cpu_topo *tp; 505 510 void *addr; 506 511 u32 nr, i; 507 - size_t sz, sz_id; 512 + size_t sz; 508 513 long ncpus; 509 514 int ret = -1; 510 515 ··· 515 520 nr = (u32)(ncpus & UINT_MAX); 516 521 517 522 sz = nr * sizeof(char *); 518 - sz_id = nr * sizeof(int); 519 523 520 - addr = calloc(1, sizeof(*tp) + 2 * sz + 2 * sz_id); 524 + addr = calloc(1, sizeof(*tp) + 2 * sz); 521 525 if (!addr) 522 526 return NULL; 523 527 ··· 526 532 tp->core_siblings = addr; 527 533 addr += sz; 528 534 tp->thread_siblings = addr; 529 - addr += sz; 530 - tp->core_id = addr; 531 - addr += sz_id; 532 - tp->phy_pkg_id = addr; 533 535 534 536 for (i = 0; i < nr; i++) { 535 537 ret = build_cpu_topo(tp, i); ··· 544 554 { 545 555 struct cpu_topo *tp; 546 556 u32 i; 547 - int ret; 557 + int ret, j; 548 558 549 559 tp = build_cpu_topology(); 550 560 if (!tp) ··· 569 579 break; 570 580 } 571 581 572 - for (i = 0; i < tp->cpu_nr; i++) { 573 - ret = do_write(fd, &tp->core_id[i], sizeof(int)); 582 + ret = perf_env__read_cpu_topology_map(&perf_env); 583 + if (ret < 0) 584 + goto done; 585 + 586 + for (j = 0; j < perf_env.nr_cpus_avail; j++) { 587 + ret = do_write(fd, &perf_env.cpu[j].core_id, 588 + sizeof(perf_env.cpu[j].core_id)); 574 589 if (ret < 0) 575 590 return ret; 576 - ret = do_write(fd, &tp->phy_pkg_id[i], sizeof(int)); 591 + ret = do_write(fd, &perf_env.cpu[j].socket_id, 592 + sizeof(perf_env.cpu[j].socket_id)); 577 593 if (ret < 0) 578 594 return ret; 579 595 }