btf_encoder: Move find_all_percpu_vars in generic collect_symbols

Move find_all_percpu_vars() under generic collect_symbols() that walks
over symbols and calls collect_percpu_var().

We will add another collect function that needs to go through all the
symbols, so it's better we go through them just once.

There's no functional change intended.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Hao Luo <haoluo@google.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Frank Ch. Eigler <fche@redhat.com>
Cc: Mark Wieelard <mjw@redhat.com>
Cc: Yonghong Song <yhs@fb.com>
Cc: bpf@vger.kernel.org
Cc: dwarves@vger.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Jiri Olsa 2020-10-31 23:31:30 +01:00 committed by Arnaldo Carvalho de Melo
parent 863e6f0f2c
commit 7b1af3f484
1 changed files with 67 additions and 57 deletions

View File

@ -250,7 +250,65 @@ static bool percpu_var_exists(uint64_t addr, uint32_t *sz, const char **name)
return true;
}
static int find_all_percpu_vars(struct btf_elf *btfe)
static int collect_percpu_var(struct btf_elf *btfe, GElf_Sym *sym)
{
const char *sym_name;
uint64_t addr;
uint32_t size;
/* compare a symbol's shndx to determine if it's a percpu variable */
if (elf_sym__section(sym) != btfe->percpu_shndx)
return 0;
if (elf_sym__type(sym) != STT_OBJECT)
return 0;
addr = elf_sym__value(sym);
/*
* Store only those symbols that have allocated space in the percpu section.
* This excludes the following three types of symbols:
*
* 1. __ADDRESSABLE(sym), which are forcely emitted as symbols.
* 2. __UNIQUE_ID(prefix), which are introduced to generate unique ids.
* 3. __exitcall(fn), functions which are labeled as exit calls.
*
* In addition, the variables defined using DEFINE_PERCPU_FIRST are
* also not included, which currently includes:
*
* 1. fixed_percpu_data
*/
if (!addr)
return 0;
size = elf_sym__size(sym);
if (!size)
return 0; /* ignore zero-sized symbols */
sym_name = elf_sym__name(sym, btfe->symtab);
if (!btf_name_valid(sym_name)) {
dump_invalid_symbol("Found symbol of invalid name when encoding btf",
sym_name, btf_elf__verbose, btf_elf__force);
if (btf_elf__force)
return 0;
return -1;
}
if (btf_elf__verbose)
printf("Found per-CPU symbol '%s' at address 0x%lx\n", sym_name, addr);
if (percpu_var_cnt == MAX_PERCPU_VAR_CNT) {
fprintf(stderr, "Reached the limit of per-CPU variables: %d\n",
MAX_PERCPU_VAR_CNT);
return -1;
}
percpu_vars[percpu_var_cnt].addr = addr;
percpu_vars[percpu_var_cnt].sz = size;
percpu_vars[percpu_var_cnt].name = sym_name;
percpu_var_cnt++;
return 0;
}
static int collect_symbols(struct btf_elf *btfe, bool collect_percpu_vars)
{
uint32_t core_id;
GElf_Sym sym;
@ -260,65 +318,17 @@ static int find_all_percpu_vars(struct btf_elf *btfe)
/* search within symtab for percpu variables */
elf_symtab__for_each_symbol(btfe->symtab, core_id, sym) {
const char *sym_name;
uint64_t addr;
uint32_t size;
/* compare a symbol's shndx to determine if it's a percpu variable */
if (elf_sym__section(&sym) != btfe->percpu_shndx)
continue;
if (elf_sym__type(&sym) != STT_OBJECT)
continue;
addr = elf_sym__value(&sym);
/*
* Store only those symbols that have allocated space in the percpu section.
* This excludes the following three types of symbols:
*
* 1. __ADDRESSABLE(sym), which are forcely emitted as symbols.
* 2. __UNIQUE_ID(prefix), which are introduced to generate unique ids.
* 3. __exitcall(fn), functions which are labeled as exit calls.
*
* In addition, the variables defined using DEFINE_PERCPU_FIRST are
* also not included, which currently includes:
*
* 1. fixed_percpu_data
*/
if (!addr)
continue;
size = elf_sym__size(&sym);
if (!size)
continue; /* ignore zero-sized symbols */
sym_name = elf_sym__name(&sym, btfe->symtab);
if (!btf_name_valid(sym_name)) {
dump_invalid_symbol("Found symbol of invalid name when encoding btf",
sym_name, btf_elf__verbose, btf_elf__force);
if (btf_elf__force)
continue;
if (collect_percpu_vars && collect_percpu_var(btfe, &sym))
return -1;
}
if (btf_elf__verbose)
printf("Found per-CPU symbol '%s' at address 0x%lx\n", sym_name, addr);
if (percpu_var_cnt == MAX_PERCPU_VAR_CNT) {
fprintf(stderr, "Reached the limit of per-CPU variables: %d\n",
MAX_PERCPU_VAR_CNT);
return -1;
}
percpu_vars[percpu_var_cnt].addr = addr;
percpu_vars[percpu_var_cnt].sz = size;
percpu_vars[percpu_var_cnt].name = sym_name;
percpu_var_cnt++;
}
if (percpu_var_cnt)
qsort(percpu_vars, percpu_var_cnt, sizeof(percpu_vars[0]), percpu_var_cmp);
if (collect_percpu_vars) {
if (percpu_var_cnt)
qsort(percpu_vars, percpu_var_cnt, sizeof(percpu_vars[0]), percpu_var_cmp);
if (btf_elf__verbose)
printf("Found %d per-CPU variables!\n", percpu_var_cnt);
if (btf_elf__verbose)
printf("Found %d per-CPU variables!\n", percpu_var_cnt);
}
return 0;
}
@ -347,7 +357,7 @@ int cu__encode_btf(struct cu *cu, int verbose, bool force,
if (!btfe)
return -1;
if (!skip_encoding_vars && find_all_percpu_vars(btfe))
if (collect_symbols(btfe, !skip_encoding_vars))
goto out;
has_index_type = false;