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

perf cpumap: Convert cpu_map.refcnt from atomic_t to refcount_t

The refcount_t type and corresponding API should be used instead of atomic_t
when the variable is used as a reference counter.

This allows to avoid accidental refcounter overflows that might lead to
use-after-free situations.

Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
Signed-off-by: David Windsor <dwindsor@gmail.com>
Signed-off-by: Hans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: Kees Kook <keescook@chromium.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: David Windsor <dwindsor@gmail.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Hans Liljestrand <ishkamiel@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kees Kook <keescook@chromium.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Matija Glavinic Pecotic <matija.glavinic-pecotic.ext@nokia.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: alsa-devel@alsa-project.org
Link: http://lkml.kernel.org/r/1487691303-31858-3-git-send-email-elena.reshetova@intel.com
[ fixed mixed conversion to refcount in tests/cpumap.c ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Elena Reshetova and committed by
Arnaldo Carvalho de Melo
ec09a42a 79c5fe6d

+11 -11
+1 -1
tools/perf/tests/cpumap.c
··· 66 66 TEST_ASSERT_VAL("wrong nr", map->nr == 2); 67 67 TEST_ASSERT_VAL("wrong cpu", map->map[0] == 1); 68 68 TEST_ASSERT_VAL("wrong cpu", map->map[1] == 256); 69 - TEST_ASSERT_VAL("wrong refcnt", atomic_read(&map->refcnt) == 1); 69 + TEST_ASSERT_VAL("wrong refcnt", refcount_read(&map->refcnt) == 1); 70 70 cpu_map__put(map); 71 71 return 0; 72 72 }
+8 -8
tools/perf/util/cpumap.c
··· 29 29 cpus->map[i] = i; 30 30 31 31 cpus->nr = nr_cpus; 32 - atomic_set(&cpus->refcnt, 1); 32 + refcount_set(&cpus->refcnt, 1); 33 33 } 34 34 35 35 return cpus; ··· 43 43 if (cpus != NULL) { 44 44 cpus->nr = nr_cpus; 45 45 memcpy(cpus->map, tmp_cpus, payload_size); 46 - atomic_set(&cpus->refcnt, 1); 46 + refcount_set(&cpus->refcnt, 1); 47 47 } 48 48 49 49 return cpus; ··· 252 252 if (cpus != NULL) { 253 253 cpus->nr = 1; 254 254 cpus->map[0] = -1; 255 - atomic_set(&cpus->refcnt, 1); 255 + refcount_set(&cpus->refcnt, 1); 256 256 } 257 257 258 258 return cpus; ··· 269 269 for (i = 0; i < nr; i++) 270 270 cpus->map[i] = -1; 271 271 272 - atomic_set(&cpus->refcnt, 1); 272 + refcount_set(&cpus->refcnt, 1); 273 273 } 274 274 275 275 return cpus; ··· 278 278 static void cpu_map__delete(struct cpu_map *map) 279 279 { 280 280 if (map) { 281 - WARN_ONCE(atomic_read(&map->refcnt) != 0, 281 + WARN_ONCE(refcount_read(&map->refcnt) != 0, 282 282 "cpu_map refcnt unbalanced\n"); 283 283 free(map); 284 284 } ··· 287 287 struct cpu_map *cpu_map__get(struct cpu_map *map) 288 288 { 289 289 if (map) 290 - atomic_inc(&map->refcnt); 290 + refcount_inc(&map->refcnt); 291 291 return map; 292 292 } 293 293 294 294 void cpu_map__put(struct cpu_map *map) 295 295 { 296 - if (map && atomic_dec_and_test(&map->refcnt)) 296 + if (map && refcount_dec_and_test(&map->refcnt)) 297 297 cpu_map__delete(map); 298 298 } 299 299 ··· 357 357 /* ensure we process id in increasing order */ 358 358 qsort(c->map, c->nr, sizeof(int), cmp_ids); 359 359 360 - atomic_set(&c->refcnt, 1); 360 + refcount_set(&c->refcnt, 1); 361 361 *res = c; 362 362 return 0; 363 363 }
+2 -2
tools/perf/util/cpumap.h
··· 3 3 4 4 #include <stdio.h> 5 5 #include <stdbool.h> 6 - #include <linux/atomic.h> 6 + #include <linux/refcount.h> 7 7 8 8 #include "perf.h" 9 9 #include "util/debug.h" 10 10 11 11 struct cpu_map { 12 - atomic_t refcnt; 12 + refcount_t refcnt; 13 13 int nr; 14 14 int map[]; 15 15 };