aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/ftrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace/ftrace.c')
-rw-r--r--kernel/trace/ftrace.c56
1 files changed, 32 insertions, 24 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 3718d55fb4c3..f3716bf04df6 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -291,7 +291,9 @@ function_stat_next(void *v, int idx)
291 pg = (struct ftrace_profile_page *)((unsigned long)rec & PAGE_MASK); 291 pg = (struct ftrace_profile_page *)((unsigned long)rec & PAGE_MASK);
292 292
293 again: 293 again:
294 rec++; 294 if (idx != 0)
295 rec++;
296
295 if ((void *)rec >= (void *)&pg->records[pg->index]) { 297 if ((void *)rec >= (void *)&pg->records[pg->index]) {
296 pg = pg->next; 298 pg = pg->next;
297 if (!pg) 299 if (!pg)
@@ -1417,10 +1419,20 @@ static void *t_hash_start(struct seq_file *m, loff_t *pos)
1417{ 1419{
1418 struct ftrace_iterator *iter = m->private; 1420 struct ftrace_iterator *iter = m->private;
1419 void *p = NULL; 1421 void *p = NULL;
1422 loff_t l;
1423
1424 if (!(iter->flags & FTRACE_ITER_HASH))
1425 *pos = 0;
1420 1426
1421 iter->flags |= FTRACE_ITER_HASH; 1427 iter->flags |= FTRACE_ITER_HASH;
1422 1428
1423 return t_hash_next(m, p, pos); 1429 iter->hidx = 0;
1430 for (l = 0; l <= *pos; ) {
1431 p = t_hash_next(m, p, &l);
1432 if (!p)
1433 break;
1434 }
1435 return p;
1424} 1436}
1425 1437
1426static int t_hash_show(struct seq_file *m, void *v) 1438static int t_hash_show(struct seq_file *m, void *v)
@@ -1467,8 +1479,6 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
1467 iter->pg = iter->pg->next; 1479 iter->pg = iter->pg->next;
1468 iter->idx = 0; 1480 iter->idx = 0;
1469 goto retry; 1481 goto retry;
1470 } else {
1471 iter->idx = -1;
1472 } 1482 }
1473 } else { 1483 } else {
1474 rec = &iter->pg->records[iter->idx++]; 1484 rec = &iter->pg->records[iter->idx++];
@@ -1497,6 +1507,7 @@ static void *t_start(struct seq_file *m, loff_t *pos)
1497{ 1507{
1498 struct ftrace_iterator *iter = m->private; 1508 struct ftrace_iterator *iter = m->private;
1499 void *p = NULL; 1509 void *p = NULL;
1510 loff_t l;
1500 1511
1501 mutex_lock(&ftrace_lock); 1512 mutex_lock(&ftrace_lock);
1502 /* 1513 /*
@@ -1508,23 +1519,21 @@ static void *t_start(struct seq_file *m, loff_t *pos)
1508 if (*pos > 0) 1519 if (*pos > 0)
1509 return t_hash_start(m, pos); 1520 return t_hash_start(m, pos);
1510 iter->flags |= FTRACE_ITER_PRINTALL; 1521 iter->flags |= FTRACE_ITER_PRINTALL;
1511 (*pos)++;
1512 return iter; 1522 return iter;
1513 } 1523 }
1514 1524
1515 if (iter->flags & FTRACE_ITER_HASH) 1525 if (iter->flags & FTRACE_ITER_HASH)
1516 return t_hash_start(m, pos); 1526 return t_hash_start(m, pos);
1517 1527
1518 if (*pos > 0) { 1528 iter->pg = ftrace_pages_start;
1519 if (iter->idx < 0) 1529 iter->idx = 0;
1520 return p; 1530 for (l = 0; l <= *pos; ) {
1521 (*pos)--; 1531 p = t_next(m, p, &l);
1522 iter->idx--; 1532 if (!p)
1533 break;
1523 } 1534 }
1524 1535
1525 p = t_next(m, p, pos); 1536 if (!p && iter->flags & FTRACE_ITER_FILTER)
1526
1527 if (!p)
1528 return t_hash_start(m, pos); 1537 return t_hash_start(m, pos);
1529 1538
1530 return p; 1539 return p;
@@ -2500,32 +2509,31 @@ int ftrace_graph_count;
2500unsigned long ftrace_graph_funcs[FTRACE_GRAPH_MAX_FUNCS] __read_mostly; 2509unsigned long ftrace_graph_funcs[FTRACE_GRAPH_MAX_FUNCS] __read_mostly;
2501 2510
2502static void * 2511static void *
2503g_next(struct seq_file *m, void *v, loff_t *pos) 2512__g_next(struct seq_file *m, loff_t *pos)
2504{ 2513{
2505 unsigned long *array = m->private; 2514 unsigned long *array = m->private;
2506 int index = *pos;
2507 2515
2508 (*pos)++; 2516 if (*pos >= ftrace_graph_count)
2509
2510 if (index >= ftrace_graph_count)
2511 return NULL; 2517 return NULL;
2518 return &array[*pos];
2519}
2512 2520
2513 return &array[index]; 2521static void *
2522g_next(struct seq_file *m, void *v, loff_t *pos)
2523{
2524 (*pos)++;
2525 return __g_next(m, pos);
2514} 2526}
2515 2527
2516static void *g_start(struct seq_file *m, loff_t *pos) 2528static void *g_start(struct seq_file *m, loff_t *pos)
2517{ 2529{
2518 void *p = NULL;
2519
2520 mutex_lock(&graph_lock); 2530 mutex_lock(&graph_lock);
2521 2531
2522 /* Nothing, tell g_show to print all functions are enabled */ 2532 /* Nothing, tell g_show to print all functions are enabled */
2523 if (!ftrace_graph_count && !*pos) 2533 if (!ftrace_graph_count && !*pos)
2524 return (void *)1; 2534 return (void *)1;
2525 2535
2526 p = g_next(m, p, pos); 2536 return __g_next(m, pos);
2527
2528 return p;
2529} 2537}
2530 2538
2531static void g_stop(struct seq_file *m, void *p) 2539static void g_stop(struct seq_file *m, void *p)