166 lines · c
1// SPDX-License-Identifier: GPL-2.02#include <inttypes.h>3#include <linux/compiler.h>4#include <linux/kernel.h>5#include "tests.h"6#include "map.h"7#include "maps.h"8#include "dso.h"9#include "debug.h"10 11struct map_def {12 const char *name;13 u64 start;14 u64 end;15};16 17struct check_maps_cb_args {18 struct map_def *merged;19 unsigned int i;20};21 22static int check_maps_cb(struct map *map, void *data)23{24 struct check_maps_cb_args *args = data;25 struct map_def *merged = &args->merged[args->i];26 27 if (map__start(map) != merged->start ||28 map__end(map) != merged->end ||29 strcmp(dso__name(map__dso(map)), merged->name) ||30 refcount_read(map__refcnt(map)) != 1) {31 return 1;32 }33 args->i++;34 return 0;35}36 37static int failed_cb(struct map *map, void *data __maybe_unused)38{39 pr_debug("\tstart: %" PRIu64 " end: %" PRIu64 " name: '%s' refcnt: %d\n",40 map__start(map),41 map__end(map),42 dso__name(map__dso(map)),43 refcount_read(map__refcnt(map)));44 45 return 0;46}47 48static int check_maps(struct map_def *merged, unsigned int size, struct maps *maps)49{50 bool failed = false;51 52 if (maps__nr_maps(maps) != size) {53 pr_debug("Expected %d maps, got %d", size, maps__nr_maps(maps));54 failed = true;55 } else {56 struct check_maps_cb_args args = {57 .merged = merged,58 .i = 0,59 };60 failed = maps__for_each_map(maps, check_maps_cb, &args);61 }62 if (failed) {63 pr_debug("Expected:\n");64 for (unsigned int i = 0; i < size; i++) {65 pr_debug("\tstart: %" PRIu64 " end: %" PRIu64 " name: '%s' refcnt: 1\n",66 merged[i].start, merged[i].end, merged[i].name);67 }68 pr_debug("Got:\n");69 maps__for_each_map(maps, failed_cb, NULL);70 }71 return failed ? TEST_FAIL : TEST_OK;72}73 74static int test__maps__merge_in(struct test_suite *t __maybe_unused, int subtest __maybe_unused)75{76 unsigned int i;77 struct map_def bpf_progs[] = {78 { "bpf_prog_1", 200, 300 },79 { "bpf_prog_2", 500, 600 },80 { "bpf_prog_3", 800, 900 },81 };82 struct map_def merged12[] = {83 { "kcore1", 100, 200 },84 { "bpf_prog_1", 200, 300 },85 { "kcore1", 300, 500 },86 { "bpf_prog_2", 500, 600 },87 { "kcore1", 600, 800 },88 { "bpf_prog_3", 800, 900 },89 { "kcore1", 900, 1000 },90 };91 struct map_def merged3[] = {92 { "kcore1", 100, 200 },93 { "bpf_prog_1", 200, 300 },94 { "kcore1", 300, 500 },95 { "bpf_prog_2", 500, 600 },96 { "kcore1", 600, 800 },97 { "bpf_prog_3", 800, 900 },98 { "kcore1", 900, 1000 },99 { "kcore3", 1000, 1100 },100 };101 struct map *map_kcore1, *map_kcore2, *map_kcore3;102 int ret;103 struct maps *maps = maps__new(NULL);104 105 TEST_ASSERT_VAL("failed to create maps", maps);106 107 for (i = 0; i < ARRAY_SIZE(bpf_progs); i++) {108 struct map *map;109 110 map = dso__new_map(bpf_progs[i].name);111 TEST_ASSERT_VAL("failed to create map", map);112 113 map__set_start(map, bpf_progs[i].start);114 map__set_end(map, bpf_progs[i].end);115 TEST_ASSERT_VAL("failed to insert map", maps__insert(maps, map) == 0);116 map__put(map);117 }118 119 map_kcore1 = dso__new_map("kcore1");120 TEST_ASSERT_VAL("failed to create map", map_kcore1);121 122 map_kcore2 = dso__new_map("kcore2");123 TEST_ASSERT_VAL("failed to create map", map_kcore2);124 125 map_kcore3 = dso__new_map("kcore3");126 TEST_ASSERT_VAL("failed to create map", map_kcore3);127 128 /* kcore1 map overlaps over all bpf maps */129 map__set_start(map_kcore1, 100);130 map__set_end(map_kcore1, 1000);131 132 /* kcore2 map hides behind bpf_prog_2 */133 map__set_start(map_kcore2, 550);134 map__set_end(map_kcore2, 570);135 136 /* kcore3 map hides behind bpf_prog_3, kcore1 and adds new map */137 map__set_start(map_kcore3, 880);138 map__set_end(map_kcore3, 1100);139 140 ret = maps__merge_in(maps, map_kcore1);141 TEST_ASSERT_VAL("failed to merge map", !ret);142 143 ret = check_maps(merged12, ARRAY_SIZE(merged12), maps);144 TEST_ASSERT_VAL("merge check failed", !ret);145 146 ret = maps__merge_in(maps, map_kcore2);147 TEST_ASSERT_VAL("failed to merge map", !ret);148 149 ret = check_maps(merged12, ARRAY_SIZE(merged12), maps);150 TEST_ASSERT_VAL("merge check failed", !ret);151 152 ret = maps__merge_in(maps, map_kcore3);153 TEST_ASSERT_VAL("failed to merge map", !ret);154 155 ret = check_maps(merged3, ARRAY_SIZE(merged3), maps);156 TEST_ASSERT_VAL("merge check failed", !ret);157 158 maps__zput(maps);159 map__zput(map_kcore1);160 map__zput(map_kcore2);161 map__zput(map_kcore3);162 return TEST_OK;163}164 165DEFINE_SUITE("maps__merge_in", maps__merge_in);166