aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2012-04-25 10:14:43 -0400
committerSteven Rostedt <rostedt@goodmis.org>2012-05-16 19:58:46 -0400
commit9644302e3315e7e36495d230d5ac7125a316d33e (patch)
tree63695acb86c89f5617820937ed254d9638894eef /kernel/trace
parent706c81f87f84adbcf1f6553b9e6b69b3e28fc35a (diff)
ftrace: Speed up search by skipping pages by address
As all records in a page of the ftrace table are sorted, we can speed up the search algorithm by checking if the address to look for falls in between the first and last record ip on the page. This speeds up both the ftrace_location() and ftrace_text_reserved() algorithms, as it can skip full pages when the search address is not in them. Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace')
-rw-r--r--kernel/trace/ftrace.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index e10f9e522c44..fc93562a6654 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -1411,6 +1411,8 @@ int ftrace_location(unsigned long ip)
1411 key.ip = ip; 1411 key.ip = ip;
1412 1412
1413 for (pg = ftrace_pages_start; pg; pg = pg->next) { 1413 for (pg = ftrace_pages_start; pg; pg = pg->next) {
1414 if (ip < pg->records[0].ip || ip > pg->records[pg->index - 1].ip)
1415 continue;
1414 rec = bsearch(&key, pg->records, pg->index, 1416 rec = bsearch(&key, pg->records, pg->index,
1415 sizeof(struct dyn_ftrace), 1417 sizeof(struct dyn_ftrace),
1416 ftrace_cmp_recs); 1418 ftrace_cmp_recs);
@@ -1571,16 +1573,24 @@ void ftrace_bug(int failed, unsigned long ip)
1571 1573
1572 1574
1573/* Return 1 if the address range is reserved for ftrace */ 1575/* Return 1 if the address range is reserved for ftrace */
1574int ftrace_text_reserved(void *start, void *end) 1576int ftrace_text_reserved(void *s, void *e)
1575{ 1577{
1576 struct dyn_ftrace *rec; 1578 struct dyn_ftrace *rec;
1577 struct ftrace_page *pg; 1579 struct ftrace_page *pg;
1580 unsigned long start = (unsigned long)s;
1581 unsigned long end = (unsigned long)e;
1582 int i;
1578 1583
1579 do_for_each_ftrace_rec(pg, rec) { 1584 for (pg = ftrace_pages_start; pg; pg = pg->next) {
1580 if (rec->ip <= (unsigned long)end && 1585 if (end < pg->records[0].ip ||
1581 rec->ip + MCOUNT_INSN_SIZE > (unsigned long)start) 1586 start >= (pg->records[pg->index - 1].ip + MCOUNT_INSN_SIZE))
1582 return 1; 1587 continue;
1583 } while_for_each_ftrace_rec(); 1588 for (i = 0; i < pg->index; i++) {
1589 rec = &pg->records[i];
1590 if (rec->ip <= end && rec->ip + MCOUNT_INSN_SIZE > start)
1591 return 1;
1592 }
1593 }
1584 return 0; 1594 return 0;
1585} 1595}
1586 1596