perf cpumap: Maintain cpumaps ordered and without dups
authorAndi Kleen <ak@linux.intel.com>
Thu, 21 Nov 2019 00:15:13 +0000 (16:15 -0800)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Fri, 29 Nov 2019 15:20:45 +0000 (12:20 -0300)
Enforce this in _trim()

Needed for followon change.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Link: http://lore.kernel.org/lkml/20191121001522.180827-4-andi@firstfloor.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/lib/cpumap.c

index 2ca1fafa620dfca8ee992b87eb35fe5c36220d0f..d81656b4635eb2009676cf343dd38fecea1ea774 100644 (file)
@@ -68,14 +68,28 @@ static struct perf_cpu_map *cpu_map__default_new(void)
        return cpus;
 }
 
+static int cmp_int(const void *a, const void *b)
+{
+       return *(const int *)a - *(const int*)b;
+}
+
 static struct perf_cpu_map *cpu_map__trim_new(int nr_cpus, int *tmp_cpus)
 {
        size_t payload_size = nr_cpus * sizeof(int);
        struct perf_cpu_map *cpus = malloc(sizeof(*cpus) + payload_size);
+       int i, j;
 
        if (cpus != NULL) {
-               cpus->nr = nr_cpus;
                memcpy(cpus->map, tmp_cpus, payload_size);
+               qsort(cpus->map, nr_cpus, sizeof(int), cmp_int);
+               /* Remove dups */
+               j = 0;
+               for (i = 0; i < nr_cpus; i++) {
+                       if (i == 0 || cpus->map[i] != cpus->map[i - 1])
+                               cpus->map[j++] = cpus->map[i];
+               }
+               cpus->nr = j;
+               assert(j <= nr_cpus);
                refcount_set(&cpus->refcnt, 1);
        }