diff options
author | Steven Rostedt <srostedt@redhat.com> | 2012-04-25 13:48:13 -0400 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2012-05-16 19:58:48 -0400 |
commit | a650e02a528ab9d6d6f0b8b57745c32f2a138459 (patch) | |
tree | 34bf32bc4c3b8ccec7e33dbe12a26d51075f779a /kernel/trace/ftrace.c | |
parent | 9644302e3315e7e36495d230d5ac7125a316d33e (diff) |
ftrace: Consolidate ftrace_location() and ftrace_text_reserved()
Both ftrace_location() and ftrace_text_reserved() do basically the same thing.
They search to see if an address is in the ftace table (contains an address
that may change from nop to call ftrace_caller). The difference is
that ftrace_location() searches a single address, but ftrace_text_reserved()
searches a range.
This also makes the ftrace_text_reserved() faster as it now uses a bsearch()
instead of linearly searching all the addresses within a page.
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace/ftrace.c')
-rw-r--r-- | kernel/trace/ftrace.c | 80 |
1 files changed, 40 insertions, 40 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index fc93562a6654..dd091c84b57f 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
@@ -1383,35 +1383,28 @@ ftrace_ops_test(struct ftrace_ops *ops, unsigned long ip) | |||
1383 | 1383 | ||
1384 | static int ftrace_cmp_recs(const void *a, const void *b) | 1384 | static int ftrace_cmp_recs(const void *a, const void *b) |
1385 | { | 1385 | { |
1386 | const struct dyn_ftrace *reca = a; | 1386 | const struct dyn_ftrace *key = a; |
1387 | const struct dyn_ftrace *recb = b; | 1387 | const struct dyn_ftrace *rec = b; |
1388 | 1388 | ||
1389 | if (reca->ip > recb->ip) | 1389 | if (key->flags < rec->ip) |
1390 | return 1; | ||
1391 | if (reca->ip < recb->ip) | ||
1392 | return -1; | 1390 | return -1; |
1391 | if (key->ip >= rec->ip + MCOUNT_INSN_SIZE) | ||
1392 | return 1; | ||
1393 | return 0; | 1393 | return 0; |
1394 | } | 1394 | } |
1395 | 1395 | ||
1396 | /** | 1396 | static int ftrace_location_range(unsigned long start, unsigned long end) |
1397 | * ftrace_location - return true if the ip giving is a traced location | ||
1398 | * @ip: the instruction pointer to check | ||
1399 | * | ||
1400 | * Returns 1 if @ip given is a pointer to a ftrace location. | ||
1401 | * That is, the instruction that is either a NOP or call to | ||
1402 | * the function tracer. It checks the ftrace internal tables to | ||
1403 | * determine if the address belongs or not. | ||
1404 | */ | ||
1405 | int ftrace_location(unsigned long ip) | ||
1406 | { | 1397 | { |
1407 | struct ftrace_page *pg; | 1398 | struct ftrace_page *pg; |
1408 | struct dyn_ftrace *rec; | 1399 | struct dyn_ftrace *rec; |
1409 | struct dyn_ftrace key; | 1400 | struct dyn_ftrace key; |
1410 | 1401 | ||
1411 | key.ip = ip; | 1402 | key.ip = start; |
1403 | key.flags = end; /* overload flags, as it is unsigned long */ | ||
1412 | 1404 | ||
1413 | for (pg = ftrace_pages_start; pg; pg = pg->next) { | 1405 | for (pg = ftrace_pages_start; pg; pg = pg->next) { |
1414 | if (ip < pg->records[0].ip || ip > pg->records[pg->index - 1].ip) | 1406 | if (end < pg->records[0].ip || |
1407 | start >= (pg->records[pg->index - 1].ip + MCOUNT_INSN_SIZE)) | ||
1415 | continue; | 1408 | continue; |
1416 | rec = bsearch(&key, pg->records, pg->index, | 1409 | rec = bsearch(&key, pg->records, pg->index, |
1417 | sizeof(struct dyn_ftrace), | 1410 | sizeof(struct dyn_ftrace), |
@@ -1423,6 +1416,36 @@ int ftrace_location(unsigned long ip) | |||
1423 | return 0; | 1416 | return 0; |
1424 | } | 1417 | } |
1425 | 1418 | ||
1419 | /** | ||
1420 | * ftrace_location - return true if the ip giving is a traced location | ||
1421 | * @ip: the instruction pointer to check | ||
1422 | * | ||
1423 | * Returns 1 if @ip given is a pointer to a ftrace location. | ||
1424 | * That is, the instruction that is either a NOP or call to | ||
1425 | * the function tracer. It checks the ftrace internal tables to | ||
1426 | * determine if the address belongs or not. | ||
1427 | */ | ||
1428 | int ftrace_location(unsigned long ip) | ||
1429 | { | ||
1430 | return ftrace_location_range(ip, ip); | ||
1431 | } | ||
1432 | |||
1433 | /** | ||
1434 | * ftrace_text_reserved - return true if range contains an ftrace location | ||
1435 | * @start: start of range to search | ||
1436 | * @end: end of range to search (inclusive). @end points to the last byte to check. | ||
1437 | * | ||
1438 | * Returns 1 if @start and @end contains a ftrace location. | ||
1439 | * That is, the instruction that is either a NOP or call to | ||
1440 | * the function tracer. It checks the ftrace internal tables to | ||
1441 | * determine if the address belongs or not. | ||
1442 | */ | ||
1443 | int ftrace_text_reserved(void *start, void *end) | ||
1444 | { | ||
1445 | return ftrace_location_range((unsigned long)start, | ||
1446 | (unsigned long)end); | ||
1447 | } | ||
1448 | |||
1426 | static void __ftrace_hash_rec_update(struct ftrace_ops *ops, | 1449 | static void __ftrace_hash_rec_update(struct ftrace_ops *ops, |
1427 | int filter_hash, | 1450 | int filter_hash, |
1428 | bool inc) | 1451 | bool inc) |
@@ -1571,29 +1594,6 @@ void ftrace_bug(int failed, unsigned long ip) | |||
1571 | } | 1594 | } |
1572 | } | 1595 | } |
1573 | 1596 | ||
1574 | |||
1575 | /* Return 1 if the address range is reserved for ftrace */ | ||
1576 | int ftrace_text_reserved(void *s, void *e) | ||
1577 | { | ||
1578 | struct dyn_ftrace *rec; | ||
1579 | struct ftrace_page *pg; | ||
1580 | unsigned long start = (unsigned long)s; | ||
1581 | unsigned long end = (unsigned long)e; | ||
1582 | int i; | ||
1583 | |||
1584 | for (pg = ftrace_pages_start; pg; pg = pg->next) { | ||
1585 | if (end < pg->records[0].ip || | ||
1586 | start >= (pg->records[pg->index - 1].ip + MCOUNT_INSN_SIZE)) | ||
1587 | continue; | ||
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 | } | ||
1594 | return 0; | ||
1595 | } | ||
1596 | |||
1597 | static int ftrace_check_record(struct dyn_ftrace *rec, int enable, int update) | 1597 | static int ftrace_check_record(struct dyn_ftrace *rec, int enable, int update) |
1598 | { | 1598 | { |
1599 | unsigned long flag = 0UL; | 1599 | unsigned long flag = 0UL; |