diff options
author | Alessio Igor Bogani <abogani@kernel.org> | 2011-04-20 05:10:52 -0400 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2011-05-19 03:25:27 -0400 |
commit | 403ed27846aa126ecf0b842b5b179c506b9d989c (patch) | |
tree | d47ce51b2548c80237e193b99ec159e8ef59470a /kernel/module.c | |
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>
Diffstat (limited to 'kernel/module.c')
-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 e8aa462301e7..d1db8eb56ad4 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -57,6 +57,7 @@ | |||
57 | #include <linux/kmemleak.h> | 57 | #include <linux/kmemleak.h> |
58 | #include <linux/jump_label.h> | 58 | #include <linux/jump_label.h> |
59 | #include <linux/pfn.h> | 59 | #include <linux/pfn.h> |
60 | #include <linux/bsearch.h> | ||
60 | 61 | ||
61 | #define CREATE_TRACE_POINTS | 62 | #define CREATE_TRACE_POINTS |
62 | #include <trace/events/module.h> | 63 | #include <trace/events/module.h> |
@@ -363,17 +364,27 @@ static bool check_symbol(const struct symsearch *syms, | |||
363 | return true; | 364 | return true; |
364 | } | 365 | } |
365 | 366 | ||
367 | static int cmp_name(const void *va, const void *vb) | ||
368 | { | ||
369 | const char *a; | ||
370 | const struct kernel_symbol *b; | ||
371 | a = va; b = vb; | ||
372 | return strcmp(a, b->name); | ||
373 | } | ||
374 | |||
366 | static bool find_symbol_in_section(const struct symsearch *syms, | 375 | static bool find_symbol_in_section(const struct symsearch *syms, |
367 | struct module *owner, | 376 | struct module *owner, |
368 | void *data) | 377 | void *data) |
369 | { | 378 | { |
370 | struct find_symbol_arg *fsa = data; | 379 | struct find_symbol_arg *fsa = data; |
371 | unsigned int i; | 380 | struct kernel_symbol *sym; |
381 | |||
382 | sym = bsearch(fsa->name, syms->start, syms->stop - syms->start, | ||
383 | sizeof(struct kernel_symbol), cmp_name); | ||
384 | |||
385 | if (sym != NULL && check_symbol(syms, owner, sym - syms->start, data)) | ||
386 | return true; | ||
372 | 387 | ||
373 | for (i = 0; i < syms->stop - syms->start; i++) { | ||
374 | if (strcmp(syms->start[i].name, fsa->name) == 0) | ||
375 | return check_symbol(syms, owner, i, data); | ||
376 | } | ||
377 | return false; | 388 | return false; |
378 | } | 389 | } |
379 | 390 | ||