// SPDX-License-Identifier: GPL-2.0-or-later /* * Test the function and performance of kallsyms * * Copyright (C) Huawei Technologies Co., Ltd., 2022 * * Authors: Zhen Lei <thunder.leizhen@huawei.com> Huawei
*/
struct test_stat { int min; int max; int save_cnt; int real_cnt; int perf;
u64 sum; char *name; unsignedlong addr; unsignedlong addrs[MAX_NUM_OF_RECORDS];
};
/* * A symbol name cannot start with a number. This stub name helps us * traverse the entire symbol table without finding a match. It's used * for subsequent performance tests, and its length is the average * length of all symbol names.
*/
memset(stub_name, '4', sizeof(stub_name));
pos = total_len / kallsyms_num_syms;
stub_name[pos] = 0;
pos = 0;
num = 0;
off = 0; while (pos < kallsyms_num_syms) {
len = kallsyms_names[off];
num++;
off++;
pos++; if ((len & 0x80) != 0) {
len = (len & 0x7f) | (kallsyms_names[off] << 7);
num++;
off++;
}
off += len;
}
/* * 1. The length fields is not counted * 2. The memory occupied by array kallsyms_token_table[] and * kallsyms_token_index[] needs to be counted.
*/
total_size = off - num;
pos = kallsyms_token_index[0xff];
total_size += pos + strlen(&kallsyms_token_table[pos]) + 1;
total_size += 0x100 * sizeof(u16);
memset(&stat, 0, sizeof(stat));
stat.min = INT_MAX;
kallsyms_on_each_symbol(lookup_name, &stat);
pr_info("kallsyms_lookup_name() looked up %d symbols\n", stat.real_cnt);
pr_info("The time spent on each symbol is (ns): min=%d, max=%d, avg=%lld\n",
stat.min, stat.max, div_u64(stat.sum, stat.real_cnt));
}
/* * kallsyms_on_each_symbol() is too slow, randomly select some * symbols for test.
*/ if (i >= next) {
memset(stat2, 0, sizeof(*stat2));
stat2->max = INT_MAX;
stat2->name = namebuf;
kallsyms_on_each_symbol(find_symbol, stat2);
/* * kallsyms_on_each_symbol() and kallsyms_on_each_match_symbol() * need to get the same traversal result.
*/ if (stat->addr != stat2->addr ||
stat->real_cnt != stat2->real_cnt ||
memcmp(stat->addrs, stat2->addrs,
stat->save_cnt * sizeof(stat->addrs[0]))) {
pr_info("%s: mismatch between kallsyms_on_each_symbol() and kallsyms_on_each_match_symbol()\n",
namebuf); goto failed;
}
/* * The average of random increments is 128, that is, one of * them is tested every 128 symbols.
*/
get_random_bytes(&rand, sizeof(rand));
next = i + (rand & 0xff) + 1;
}
/* Need to be found at least once */ if (!stat->real_cnt) {
pr_info("%s: Never found\n", namebuf); goto failed;
}
/* * kallsyms_lookup_name() returns the address of the first * symbol found and cannot be NULL.
*/ if (!lookup_addr) {
pr_info("%s: NULL lookup_addr?!\n", namebuf); goto failed;
} if (lookup_addr != stat->addrs[0]) {
pr_info("%s: lookup_addr != stat->addrs[0]\n", namebuf); goto failed;
}
/* * If the addresses of all matching symbols are recorded, the * target address needs to be exist.
*/ if (stat->real_cnt <= MAX_NUM_OF_RECORDS) { for (j = 0; j < stat->save_cnt; j++) { if (stat->addrs[j] == addr) break;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.