| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * svghelper.c - helper functions for outputting svg |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 5 | 6 | * |
|---|
| 6 | 7 | * Authors: |
|---|
| 7 | 8 | * Arjan van de Ven <arjan@linux.intel.com> |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is free software; you can redistribute it and/or |
|---|
| 10 | | - * modify it under the terms of the GNU General Public License |
|---|
| 11 | | - * as published by the Free Software Foundation; version 2 |
|---|
| 12 | | - * of the License. |
|---|
| 13 | 9 | */ |
|---|
| 14 | 10 | |
|---|
| 15 | 11 | #include <inttypes.h> |
|---|
| .. | .. |
|---|
| 18 | 14 | #include <unistd.h> |
|---|
| 19 | 15 | #include <string.h> |
|---|
| 20 | 16 | #include <linux/bitmap.h> |
|---|
| 17 | +#include <linux/string.h> |
|---|
| 21 | 18 | #include <linux/time64.h> |
|---|
| 19 | +#include <linux/zalloc.h> |
|---|
| 20 | +#include <internal/cpumap.h> |
|---|
| 21 | +#include <perf/cpumap.h> |
|---|
| 22 | 22 | |
|---|
| 23 | | -#include "perf.h" |
|---|
| 23 | +#include "env.h" |
|---|
| 24 | 24 | #include "svghelper.h" |
|---|
| 25 | | -#include "util.h" |
|---|
| 26 | | -#include "cpumap.h" |
|---|
| 27 | 25 | |
|---|
| 28 | 26 | static u64 first_time, last_time; |
|---|
| 29 | 27 | static u64 turbo_frequency, max_freq; |
|---|
| .. | .. |
|---|
| 698 | 696 | int sib_thr_nr; |
|---|
| 699 | 697 | }; |
|---|
| 700 | 698 | |
|---|
| 701 | | -static void scan_thread_topology(int *map, struct topology *t, int cpu, int *pos) |
|---|
| 699 | +static void scan_thread_topology(int *map, struct topology *t, int cpu, |
|---|
| 700 | + int *pos, int nr_cpus) |
|---|
| 702 | 701 | { |
|---|
| 703 | 702 | int i; |
|---|
| 704 | 703 | int thr; |
|---|
| .. | .. |
|---|
| 707 | 706 | if (!test_bit(cpu, cpumask_bits(&t->sib_thr[i]))) |
|---|
| 708 | 707 | continue; |
|---|
| 709 | 708 | |
|---|
| 710 | | - for_each_set_bit(thr, |
|---|
| 711 | | - cpumask_bits(&t->sib_thr[i]), |
|---|
| 712 | | - MAX_NR_CPUS) |
|---|
| 709 | + for_each_set_bit(thr, cpumask_bits(&t->sib_thr[i]), nr_cpus) |
|---|
| 713 | 710 | if (map[thr] == -1) |
|---|
| 714 | 711 | map[thr] = (*pos)++; |
|---|
| 715 | 712 | } |
|---|
| 716 | 713 | } |
|---|
| 717 | 714 | |
|---|
| 718 | | -static void scan_core_topology(int *map, struct topology *t) |
|---|
| 715 | +static void scan_core_topology(int *map, struct topology *t, int nr_cpus) |
|---|
| 719 | 716 | { |
|---|
| 720 | 717 | int pos = 0; |
|---|
| 721 | 718 | int i; |
|---|
| 722 | 719 | int cpu; |
|---|
| 723 | 720 | |
|---|
| 724 | 721 | for (i = 0; i < t->sib_core_nr; i++) |
|---|
| 725 | | - for_each_set_bit(cpu, |
|---|
| 726 | | - cpumask_bits(&t->sib_core[i]), |
|---|
| 727 | | - MAX_NR_CPUS) |
|---|
| 728 | | - scan_thread_topology(map, t, cpu, &pos); |
|---|
| 722 | + for_each_set_bit(cpu, cpumask_bits(&t->sib_core[i]), nr_cpus) |
|---|
| 723 | + scan_thread_topology(map, t, cpu, &pos, nr_cpus); |
|---|
| 729 | 724 | } |
|---|
| 730 | 725 | |
|---|
| 731 | | -static int str_to_bitmap(char *s, cpumask_t *b) |
|---|
| 726 | +static int str_to_bitmap(char *s, cpumask_t *b, int nr_cpus) |
|---|
| 732 | 727 | { |
|---|
| 733 | 728 | int i; |
|---|
| 734 | 729 | int ret = 0; |
|---|
| 735 | | - struct cpu_map *m; |
|---|
| 730 | + struct perf_cpu_map *m; |
|---|
| 736 | 731 | int c; |
|---|
| 737 | 732 | |
|---|
| 738 | | - m = cpu_map__new(s); |
|---|
| 733 | + m = perf_cpu_map__new(s); |
|---|
| 739 | 734 | if (!m) |
|---|
| 740 | 735 | return -1; |
|---|
| 741 | 736 | |
|---|
| 742 | 737 | for (i = 0; i < m->nr; i++) { |
|---|
| 743 | 738 | c = m->map[i]; |
|---|
| 744 | | - if (c >= MAX_NR_CPUS) { |
|---|
| 739 | + if (c >= nr_cpus) { |
|---|
| 745 | 740 | ret = -1; |
|---|
| 746 | 741 | break; |
|---|
| 747 | 742 | } |
|---|
| .. | .. |
|---|
| 749 | 744 | set_bit(c, cpumask_bits(b)); |
|---|
| 750 | 745 | } |
|---|
| 751 | 746 | |
|---|
| 752 | | - cpu_map__put(m); |
|---|
| 747 | + perf_cpu_map__put(m); |
|---|
| 753 | 748 | |
|---|
| 754 | 749 | return ret; |
|---|
| 755 | 750 | } |
|---|
| 756 | 751 | |
|---|
| 757 | | -int svg_build_topology_map(char *sib_core, int sib_core_nr, |
|---|
| 758 | | - char *sib_thr, int sib_thr_nr) |
|---|
| 752 | +int svg_build_topology_map(struct perf_env *env) |
|---|
| 759 | 753 | { |
|---|
| 760 | | - int i; |
|---|
| 754 | + int i, nr_cpus; |
|---|
| 761 | 755 | struct topology t; |
|---|
| 756 | + char *sib_core, *sib_thr; |
|---|
| 762 | 757 | |
|---|
| 763 | | - t.sib_core_nr = sib_core_nr; |
|---|
| 764 | | - t.sib_thr_nr = sib_thr_nr; |
|---|
| 765 | | - t.sib_core = calloc(sib_core_nr, sizeof(cpumask_t)); |
|---|
| 766 | | - t.sib_thr = calloc(sib_thr_nr, sizeof(cpumask_t)); |
|---|
| 758 | + nr_cpus = min(env->nr_cpus_online, MAX_NR_CPUS); |
|---|
| 759 | + |
|---|
| 760 | + t.sib_core_nr = env->nr_sibling_cores; |
|---|
| 761 | + t.sib_thr_nr = env->nr_sibling_threads; |
|---|
| 762 | + t.sib_core = calloc(env->nr_sibling_cores, sizeof(cpumask_t)); |
|---|
| 763 | + t.sib_thr = calloc(env->nr_sibling_threads, sizeof(cpumask_t)); |
|---|
| 764 | + |
|---|
| 765 | + sib_core = env->sibling_cores; |
|---|
| 766 | + sib_thr = env->sibling_threads; |
|---|
| 767 | 767 | |
|---|
| 768 | 768 | if (!t.sib_core || !t.sib_thr) { |
|---|
| 769 | 769 | fprintf(stderr, "topology: no memory\n"); |
|---|
| 770 | 770 | goto exit; |
|---|
| 771 | 771 | } |
|---|
| 772 | 772 | |
|---|
| 773 | | - for (i = 0; i < sib_core_nr; i++) { |
|---|
| 774 | | - if (str_to_bitmap(sib_core, &t.sib_core[i])) { |
|---|
| 773 | + for (i = 0; i < env->nr_sibling_cores; i++) { |
|---|
| 774 | + if (str_to_bitmap(sib_core, &t.sib_core[i], nr_cpus)) { |
|---|
| 775 | 775 | fprintf(stderr, "topology: can't parse siblings map\n"); |
|---|
| 776 | 776 | goto exit; |
|---|
| 777 | 777 | } |
|---|
| .. | .. |
|---|
| 779 | 779 | sib_core += strlen(sib_core) + 1; |
|---|
| 780 | 780 | } |
|---|
| 781 | 781 | |
|---|
| 782 | | - for (i = 0; i < sib_thr_nr; i++) { |
|---|
| 783 | | - if (str_to_bitmap(sib_thr, &t.sib_thr[i])) { |
|---|
| 782 | + for (i = 0; i < env->nr_sibling_threads; i++) { |
|---|
| 783 | + if (str_to_bitmap(sib_thr, &t.sib_thr[i], nr_cpus)) { |
|---|
| 784 | 784 | fprintf(stderr, "topology: can't parse siblings map\n"); |
|---|
| 785 | 785 | goto exit; |
|---|
| 786 | 786 | } |
|---|
| .. | .. |
|---|
| 788 | 788 | sib_thr += strlen(sib_thr) + 1; |
|---|
| 789 | 789 | } |
|---|
| 790 | 790 | |
|---|
| 791 | | - topology_map = malloc(sizeof(int) * MAX_NR_CPUS); |
|---|
| 791 | + topology_map = malloc(sizeof(int) * nr_cpus); |
|---|
| 792 | 792 | if (!topology_map) { |
|---|
| 793 | 793 | fprintf(stderr, "topology: no memory\n"); |
|---|
| 794 | 794 | goto exit; |
|---|
| 795 | 795 | } |
|---|
| 796 | 796 | |
|---|
| 797 | | - for (i = 0; i < MAX_NR_CPUS; i++) |
|---|
| 797 | + for (i = 0; i < nr_cpus; i++) |
|---|
| 798 | 798 | topology_map[i] = -1; |
|---|
| 799 | 799 | |
|---|
| 800 | | - scan_core_topology(topology_map, &t); |
|---|
| 800 | + scan_core_topology(topology_map, &t, nr_cpus); |
|---|
| 801 | 801 | |
|---|
| 802 | 802 | return 0; |
|---|
| 803 | 803 | |
|---|