diff options
author | Alessio Igor Bogani <abogani@kernel.org> | 2011-04-20 11:10:52 +0200 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2011-05-19 16:55:27 +0930 |
commit | 403ed27846aa126ecf0b842b5b179c506b9d989c (patch) | |
tree | d47ce51b2548c80237e193b99ec159e8ef59470a | |
parent | 1a94dc35bc5c166d89913dc01a49d27a3c21a455 (diff) |
module: Use the binary search for symbols resolution
Takes advantage of the order and locates symbols using binary search.
This work was supported by a hardware donation from the CE Linux Forum.
Signed-off-by: Alessio Igor Bogani <abogani@kernel.org>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Tested-by: Dirk Behme <dirk.behme@googlemail.com>
-rw-r--r-- | kernel/module.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/kernel/module.c b/kernel/module.c index e8aa462301e..d1db8eb56ad 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -57,6 +57,7 @@ #include <linux/kmemleak.h> #include <linux/jump_label.h> #include <linux/pfn.h> +#include <linux/bsearch.h> #define CREATE_TRACE_POINTS #include <trace/events/module.h> @@ -363,17 +364,27 @@ static bool check_symbol(const struct symsearch *syms, return true; } +static int cmp_name(const void *va, const void *vb) +{ + const char *a; + const struct kernel_symbol *b; + a = va; b = vb; + return strcmp(a, b->name); +} + static bool find_symbol_in_section(const struct symsearch *syms, struct module *owner, void *data) { struct find_symbol_arg *fsa = data; - unsigned int i; + struct kernel_symbol *sym; + + sym = bsearch(fsa->name, syms->start, syms->stop - syms->start, + sizeof(struct kernel_symbol), cmp_name); + + if (sym != NULL && check_symbol(syms, owner, sym - syms->start, data)) + return true; - for (i = 0; i < syms->stop - syms->start; i++) { - if (strcmp(syms->start[i].name, fsa->name) == 0) - return check_symbol(syms, owner, i, data); - } return false; } |