aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/ftrace.c
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2012-04-25 13:48:13 -0400
committerSteven Rostedt <rostedt@goodmis.org>2012-05-16 19:58:48 -0400
commita650e02a528ab9d6d6f0b8b57745c32f2a138459 (patch)
tree34bf32bc4c3b8ccec7e33dbe12a26d51075f779a /kernel/trace/ftrace.c
parent9644302e3315e7e36495d230d5ac7125a316d33e (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.c80
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
1384static int ftrace_cmp_recs(const void *a, const void *b) 1384static 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/** 1396static 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 */
1405int 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 */
1428int 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 */
1443int ftrace_text_reserved(void *start, void *end)
1444{
1445 return ftrace_location_range((unsigned long)start,
1446 (unsigned long)end);
1447}
1448
1426static void __ftrace_hash_rec_update(struct ftrace_ops *ops, 1449static 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 */
1576int 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
1597static int ftrace_check_record(struct dyn_ftrace *rec, int enable, int update) 1597static int ftrace_check_record(struct dyn_ftrace *rec, int enable, int update)
1598{ 1598{
1599 unsigned long flag = 0UL; 1599 unsigned long flag = 0UL;