perf map: Remove kernel map before updating start and end addresses
authorJames Clark <james.clark@arm.com>
Wed, 10 Apr 2024 10:34:54 +0000 (11:34 +0100)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Fri, 12 Apr 2024 15:02:06 +0000 (12:02 -0300)
In a debug build there is validation that mmap lists are sorted when
taking a lock. In machine__update_kernel_mmap() the start and end
addresses are updated resulting in an unsorted list before the map is
removed from the list. When the map is removed, the lock is taken which
triggers the validation and the failure:

  $ perf test "object code reading"
  --- start ---
  perf: util/maps.c:88: check_invariants: Assertion `map__start(prev) <= map__start(map)' failed.
  Aborted

Fix it by updating the addresses after removal, but before insertion.
The bug depends on the ordering and type of debug info on the system and
doesn't reproduce everywhere.

Fixes: 659ad3492b913c90 ("perf maps: Switch from rbtree to lazily sorted array for addresses")
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: James Clark <james.clark@arm.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Leo Yan <leo.yan@linux.dev>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Spoorthy S <spoorts2@in.ibm.com>
Link: https://lore.kernel.org/r/20240410103458.813656-4-james.clark@arm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/machine.c

index 5eb9044bc223c36a9e5b90263e134824d17b47c5..a26c8bea58d0b6cfc73385c41390d186d22f2ffc 100644 (file)
@@ -1549,8 +1549,8 @@ static int machine__update_kernel_mmap(struct machine *machine,
        updated = map__get(orig);
 
        machine->vmlinux_map = updated;
-       machine__set_kernel_mmap(machine, start, end);
        maps__remove(machine__kernel_maps(machine), orig);
+       machine__set_kernel_mmap(machine, start, end);
        err = maps__insert(machine__kernel_maps(machine), updated);
        map__put(orig);