aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2010-09-15 04:27:31 -0400
committerIngo Molnar <mingo@elte.hu>2010-09-15 04:27:31 -0400
commit3aabae7d9dfaed60effe93662f02c19bafc18537 (patch)
treeaf94cdd69add07601d9f3f5988dfc1dc255e3886 /kernel/trace
parent79e406d7b00ab2b261ae32a59f266fd3b7af6f29 (diff)
parent57c072c7113f54f9512624d6c665db6184448782 (diff)
Merge branch 'tip/perf/core' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace into perf/core
Diffstat (limited to 'kernel/trace')
-rw-r--r--kernel/trace/ftrace.c107
-rw-r--r--kernel/trace/ring_buffer.c2
2 files changed, 78 insertions, 31 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 20aff3f1c719..65fb077ea79c 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -1358,24 +1358,29 @@ enum {
1358#define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */ 1358#define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */
1359 1359
1360struct ftrace_iterator { 1360struct ftrace_iterator {
1361 struct ftrace_page *pg; 1361 loff_t pos;
1362 int hidx; 1362 loff_t func_pos;
1363 int idx; 1363 struct ftrace_page *pg;
1364 unsigned flags; 1364 struct dyn_ftrace *func;
1365 struct trace_parser parser; 1365 struct ftrace_func_probe *probe;
1366 struct trace_parser parser;
1367 int hidx;
1368 int idx;
1369 unsigned flags;
1366}; 1370};
1367 1371
1368static void * 1372static void *
1369t_hash_next(struct seq_file *m, void *v, loff_t *pos) 1373t_hash_next(struct seq_file *m, loff_t *pos)
1370{ 1374{
1371 struct ftrace_iterator *iter = m->private; 1375 struct ftrace_iterator *iter = m->private;
1372 struct hlist_node *hnd = v; 1376 struct hlist_node *hnd = NULL;
1373 struct hlist_head *hhd; 1377 struct hlist_head *hhd;
1374 1378
1375 WARN_ON(!(iter->flags & FTRACE_ITER_HASH));
1376
1377 (*pos)++; 1379 (*pos)++;
1380 iter->pos = *pos;
1378 1381
1382 if (iter->probe)
1383 hnd = &iter->probe->node;
1379 retry: 1384 retry:
1380 if (iter->hidx >= FTRACE_FUNC_HASHSIZE) 1385 if (iter->hidx >= FTRACE_FUNC_HASHSIZE)
1381 return NULL; 1386 return NULL;
@@ -1398,7 +1403,12 @@ t_hash_next(struct seq_file *m, void *v, loff_t *pos)
1398 } 1403 }
1399 } 1404 }
1400 1405
1401 return hnd; 1406 if (WARN_ON_ONCE(!hnd))
1407 return NULL;
1408
1409 iter->probe = hlist_entry(hnd, struct ftrace_func_probe, node);
1410
1411 return iter;
1402} 1412}
1403 1413
1404static void *t_hash_start(struct seq_file *m, loff_t *pos) 1414static void *t_hash_start(struct seq_file *m, loff_t *pos)
@@ -1407,26 +1417,32 @@ static void *t_hash_start(struct seq_file *m, loff_t *pos)
1407 void *p = NULL; 1417 void *p = NULL;
1408 loff_t l; 1418 loff_t l;
1409 1419
1410 if (!(iter->flags & FTRACE_ITER_HASH)) 1420 if (iter->func_pos > *pos)
1411 *pos = 0; 1421 return NULL;
1412
1413 iter->flags |= FTRACE_ITER_HASH;
1414 1422
1415 iter->hidx = 0; 1423 iter->hidx = 0;
1416 for (l = 0; l <= *pos; ) { 1424 for (l = 0; l <= (*pos - iter->func_pos); ) {
1417 p = t_hash_next(m, p, &l); 1425 p = t_hash_next(m, &l);
1418 if (!p) 1426 if (!p)
1419 break; 1427 break;
1420 } 1428 }
1421 return p; 1429 if (!p)
1430 return NULL;
1431
1432 /* Only set this if we have an item */
1433 iter->flags |= FTRACE_ITER_HASH;
1434
1435 return iter;
1422} 1436}
1423 1437
1424static int t_hash_show(struct seq_file *m, void *v) 1438static int
1439t_hash_show(struct seq_file *m, struct ftrace_iterator *iter)
1425{ 1440{
1426 struct ftrace_func_probe *rec; 1441 struct ftrace_func_probe *rec;
1427 struct hlist_node *hnd = v;
1428 1442
1429 rec = hlist_entry(hnd, struct ftrace_func_probe, node); 1443 rec = iter->probe;
1444 if (WARN_ON_ONCE(!rec))
1445 return -EIO;
1430 1446
1431 if (rec->ops->print) 1447 if (rec->ops->print)
1432 return rec->ops->print(m, rec->ip, rec->ops, rec->data); 1448 return rec->ops->print(m, rec->ip, rec->ops, rec->data);
@@ -1447,12 +1463,13 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
1447 struct dyn_ftrace *rec = NULL; 1463 struct dyn_ftrace *rec = NULL;
1448 1464
1449 if (iter->flags & FTRACE_ITER_HASH) 1465 if (iter->flags & FTRACE_ITER_HASH)
1450 return t_hash_next(m, v, pos); 1466 return t_hash_next(m, pos);
1451 1467
1452 (*pos)++; 1468 (*pos)++;
1469 iter->pos = *pos;
1453 1470
1454 if (iter->flags & FTRACE_ITER_PRINTALL) 1471 if (iter->flags & FTRACE_ITER_PRINTALL)
1455 return NULL; 1472 return t_hash_start(m, pos);
1456 1473
1457 retry: 1474 retry:
1458 if (iter->idx >= iter->pg->index) { 1475 if (iter->idx >= iter->pg->index) {
@@ -1481,7 +1498,20 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
1481 } 1498 }
1482 } 1499 }
1483 1500
1484 return rec; 1501 if (!rec)
1502 return t_hash_start(m, pos);
1503
1504 iter->func_pos = *pos;
1505 iter->func = rec;
1506
1507 return iter;
1508}
1509
1510static void reset_iter_read(struct ftrace_iterator *iter)
1511{
1512 iter->pos = 0;
1513 iter->func_pos = 0;
1514 iter->flags &= ~(FTRACE_ITER_PRINTALL & FTRACE_ITER_HASH);
1485} 1515}
1486 1516
1487static void *t_start(struct seq_file *m, loff_t *pos) 1517static void *t_start(struct seq_file *m, loff_t *pos)
@@ -1492,6 +1522,12 @@ static void *t_start(struct seq_file *m, loff_t *pos)
1492 1522
1493 mutex_lock(&ftrace_lock); 1523 mutex_lock(&ftrace_lock);
1494 /* 1524 /*
1525 * If an lseek was done, then reset and start from beginning.
1526 */
1527 if (*pos < iter->pos)
1528 reset_iter_read(iter);
1529
1530 /*
1495 * For set_ftrace_filter reading, if we have the filter 1531 * For set_ftrace_filter reading, if we have the filter
1496 * off, we can short cut and just print out that all 1532 * off, we can short cut and just print out that all
1497 * functions are enabled. 1533 * functions are enabled.
@@ -1500,12 +1536,19 @@ static void *t_start(struct seq_file *m, loff_t *pos)
1500 if (*pos > 0) 1536 if (*pos > 0)
1501 return t_hash_start(m, pos); 1537 return t_hash_start(m, pos);
1502 iter->flags |= FTRACE_ITER_PRINTALL; 1538 iter->flags |= FTRACE_ITER_PRINTALL;
1539 /* reset in case of seek/pread */
1540 iter->flags &= ~FTRACE_ITER_HASH;
1503 return iter; 1541 return iter;
1504 } 1542 }
1505 1543
1506 if (iter->flags & FTRACE_ITER_HASH) 1544 if (iter->flags & FTRACE_ITER_HASH)
1507 return t_hash_start(m, pos); 1545 return t_hash_start(m, pos);
1508 1546
1547 /*
1548 * Unfortunately, we need to restart at ftrace_pages_start
1549 * every time we let go of the ftrace_mutex. This is because
1550 * those pointers can change without the lock.
1551 */
1509 iter->pg = ftrace_pages_start; 1552 iter->pg = ftrace_pages_start;
1510 iter->idx = 0; 1553 iter->idx = 0;
1511 for (l = 0; l <= *pos; ) { 1554 for (l = 0; l <= *pos; ) {
@@ -1514,10 +1557,14 @@ static void *t_start(struct seq_file *m, loff_t *pos)
1514 break; 1557 break;
1515 } 1558 }
1516 1559
1517 if (!p && iter->flags & FTRACE_ITER_FILTER) 1560 if (!p) {
1518 return t_hash_start(m, pos); 1561 if (iter->flags & FTRACE_ITER_FILTER)
1562 return t_hash_start(m, pos);
1519 1563
1520 return p; 1564 return NULL;
1565 }
1566
1567 return iter;
1521} 1568}
1522 1569
1523static void t_stop(struct seq_file *m, void *p) 1570static void t_stop(struct seq_file *m, void *p)
@@ -1528,16 +1575,18 @@ static void t_stop(struct seq_file *m, void *p)
1528static int t_show(struct seq_file *m, void *v) 1575static int t_show(struct seq_file *m, void *v)
1529{ 1576{
1530 struct ftrace_iterator *iter = m->private; 1577 struct ftrace_iterator *iter = m->private;
1531 struct dyn_ftrace *rec = v; 1578 struct dyn_ftrace *rec;
1532 1579
1533 if (iter->flags & FTRACE_ITER_HASH) 1580 if (iter->flags & FTRACE_ITER_HASH)
1534 return t_hash_show(m, v); 1581 return t_hash_show(m, iter);
1535 1582
1536 if (iter->flags & FTRACE_ITER_PRINTALL) { 1583 if (iter->flags & FTRACE_ITER_PRINTALL) {
1537 seq_printf(m, "#### all functions enabled ####\n"); 1584 seq_printf(m, "#### all functions enabled ####\n");
1538 return 0; 1585 return 0;
1539 } 1586 }
1540 1587
1588 rec = iter->func;
1589
1541 if (!rec) 1590 if (!rec)
1542 return 0; 1591 return 0;
1543 1592
@@ -2406,7 +2455,7 @@ static const struct file_operations ftrace_filter_fops = {
2406 .open = ftrace_filter_open, 2455 .open = ftrace_filter_open,
2407 .read = seq_read, 2456 .read = seq_read,
2408 .write = ftrace_filter_write, 2457 .write = ftrace_filter_write,
2409 .llseek = no_llseek, 2458 .llseek = ftrace_regex_lseek,
2410 .release = ftrace_filter_release, 2459 .release = ftrace_filter_release,
2411}; 2460};
2412 2461
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index ef27017caa56..4e2f03410377 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -2994,13 +2994,11 @@ static void rb_advance_reader(struct ring_buffer_per_cpu *cpu_buffer)
2994 2994
2995static void rb_advance_iter(struct ring_buffer_iter *iter) 2995static void rb_advance_iter(struct ring_buffer_iter *iter)
2996{ 2996{
2997 struct ring_buffer *buffer;
2998 struct ring_buffer_per_cpu *cpu_buffer; 2997 struct ring_buffer_per_cpu *cpu_buffer;
2999 struct ring_buffer_event *event; 2998 struct ring_buffer_event *event;
3000 unsigned length; 2999 unsigned length;
3001 3000
3002 cpu_buffer = iter->cpu_buffer; 3001 cpu_buffer = iter->cpu_buffer;
3003 buffer = cpu_buffer->buffer;
3004 3002
3005 /* 3003 /*
3006 * Check if we are at the end of the buffer. 3004 * Check if we are at the end of the buffer.