Skip to content
  • Thomas Richter's avatar
    perf test: Fix test case Merge cpu map · 0dd1979f
    Thomas Richter authored
    Commit a2408a70
    
     ("perf evlist: Maintain evlist->all_cpus")
    introduces a test case for cpumap merge operation, see functions
    perf_cpu_map__merge() and test__cpu_map_merge().
    
    The test case fails on s390 with this error message:
    
     [root@m35lp76 perf]# ./perf test -Fvvvvv 52
     52: Merge cpu map                                         :
     --- start ---
     cpumask list: 1-2,4-5,7
     perf: /root/linux/tools/include/linux/refcount.h:131:\
              refcount_sub_and_test: Assertion `!(new > val)' failed.
     Aborted (core dumped)
     [root@m35lp76 perf]#
    
    The root cause is in the function test__cpu_map_merge():
    It creates two cpu_maps named 'a' and 'b':
    
      struct perf_cpu_map *a = perf_cpu_map__new("4,2,1");
      struct perf_cpu_map *b = perf_cpu_map__new("4,5,7");
    
    and creates a third map named 'c' which is the result of
    the merge of maps a and b:
    
      struct perf_cpu_map *c = perf_cpu_map__merge(a, b);
    
    After some verifaction of the merged cpu_map all three
    of them are have their reference count reduced and are
    freed:
    
       perf_cpu_map__put(a); (1)
       perf_cpu_map__put(b);
       perf_cpu_map__put(c);
    
    The release of perf_cpu_map__put(a) is wrong. The map
    is already released and free'ed as part of the function
    
      perf_cpu_map__merge(struct perf_cpu_map *orig,
      |	              struct perf_cpu_map *other)
      +--> perf_cpu_map__put(orig);
           |
           +--> cpu_map__delete(orig)
    
    At the end perf_cpu_map_put() is called for map 'orig'
    alias 'a' and since the reference count is 1, the map
    is deleted, as can be seen by the following gdb trace:
    
     (gdb) where
     #0  tcache_put (tc_idx=0, chunk=0x156cc30) at malloc.c:2940
     #1  _int_free (av=0x3fffd49ee80 <main_arena>, p=0x156cc30,
    		     have_lock=<optimized out>) at malloc.c:4222
     #2  0x00000000012d5e78 in cpu_map__delete (map=0x156cc40) at cpumap.c:31
     #3  0x00000000012d5f7a in perf_cpu_map__put (map=0x156cc40) at cpumap.c:45
     #4  0x00000000012d723a in perf_cpu_map__merge (orig=0x156cc40,
         other=0x156cc60) at cpumap.c:343
     #5  0x000000000110cdd0 in test__cpu_map_merge (
         test=0x14ea6c8 <generic_tests+2856>, subtest=-1) at tests/cpumap.c:128
    
    Thus the perf_cpu_map__put(a) (see (1) above) frees map 'a'
    a second time and causes the failure. Fix this be removing that
    function call.
    
    Output after:
      [root@m35lp76 perf]# ./perf test -Fvvvvv 52
      52: Merge cpu map                                         :
      --- start ---
      cpumask list: 1-2,4-5,7
      ---- end ----
      Merge cpu map: Ok
      [root@m35lp76 perf]#
    
    Signed-off-by: default avatarThomas Richter <tmricht@linux.ibm.com>
    Reviewed-by: default avatarAndi Kleen <ak@linux.intel.com>
    Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
    Cc: Vasily Gorbik <gor@linux.ibm.com>
    Cc: sumanthk@linux.ibm.com
    Link: http://lore.kernel.org/lkml/20200120132011.64698-1-tmricht@linux.ibm.com
    
    
    Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
    0dd1979f