kallsyms: Add helper kallsyms_on_each_match_symbol()

ANBZ: #9733

commit 4dc533e0f2 upstream

Function kallsyms_on_each_symbol() traverses all symbols and submits each
symbol to the hook 'fn' for judgment and processing. For some cases, the
hook actually only handles the matched symbol, such as livepatch.

Because all symbols are currently sorted by name, all the symbols with the
same name are clustered together. Function kallsyms_lookup_names() gets
the start and end positions of the set corresponding to the specified
name. So we can easily and quickly traverse all the matches.

The test results are as follows (twice): (x86)
kallsyms_on_each_match_symbol:     7454,     7984
kallsyms_on_each_symbol      : 11733809, 11785803

kallsyms_on_each_match_symbol() consumes only 0.066% of
kallsyms_on_each_symbol()'s time. In other words, 1523x better
performance.

Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
Signed-off-by: beixu <zhangchengbo.zcb@alibaba-inc.com>
Reviewed-by: Artie Ding <artie.ding@linux.alibaba.com>
Reviewed-by: Xunlei Pang <xlpang@linux.alibaba.com>
Link: https://gitee.com/anolis/cloud-kernel/pulls/3680
This commit is contained in:
Zhen Lei 2022-11-02 16:49:17 +08:00 committed by 小龙
parent 843452490e
commit 73b30c9569
2 changed files with 25 additions and 0 deletions

View File

@ -79,6 +79,8 @@ unsigned long kallsyms_lookup_name(const char *name);
int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *,
unsigned long),
void *data);
int kallsyms_on_each_match_symbol(int (*fn)(void *, unsigned long),
const char *name, void *data);
extern int kallsyms_lookup_size_offset(unsigned long addr,
unsigned long *symbolsize,
@ -164,6 +166,11 @@ static inline bool kallsyms_show_value(const struct cred *cred)
return false;
}
static inline int kallsyms_on_each_match_symbol(int (*fn)(void *, unsigned long),
const char *name, void *data)
{
return -EOPNOTSUPP;
}
#endif /*CONFIG_KALLSYMS*/
static inline void print_ip_sym(const char *loglvl, unsigned long ip)

View File

@ -296,6 +296,24 @@ int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *,
}
EXPORT_SYMBOL_GPL(kallsyms_on_each_symbol);
int kallsyms_on_each_match_symbol(int (*fn)(void *, unsigned long),
const char *name, void *data)
{
int ret;
unsigned int i, start, end;
ret = kallsyms_lookup_names(name, &start, &end);
if (ret)
return 0;
for (i = start; !ret && i <= end; i++) {
ret = fn(data, kallsyms_sym_address(get_symbol_seq(i)));
cond_resched();
}
return ret;
}
static unsigned long get_symbol_pos(unsigned long addr,
unsigned long *symbolsize,
unsigned long *offset)