diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/trace/ftrace.c | 345 | ||||
-rw-r--r-- | kernel/trace/trace.c | 11 | ||||
-rw-r--r-- | kernel/trace/trace.h | 44 |
3 files changed, 386 insertions, 14 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 65b9e863056b..d2b156538162 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
@@ -47,8 +47,9 @@ | |||
47 | int ftrace_enabled __read_mostly; | 47 | int ftrace_enabled __read_mostly; |
48 | static int last_ftrace_enabled; | 48 | static int last_ftrace_enabled; |
49 | 49 | ||
50 | /* ftrace_pid_trace >= 0 will only trace threads with this pid */ | 50 | /* set when tracing only a pid */ |
51 | static int ftrace_pid_trace = -1; | 51 | struct pid *ftrace_pid_trace; |
52 | static struct pid * const ftrace_swapper_pid = (struct pid *)1; | ||
52 | 53 | ||
53 | /* Quick disabling of function tracer. */ | 54 | /* Quick disabling of function tracer. */ |
54 | int function_trace_stop; | 55 | int function_trace_stop; |
@@ -90,7 +91,7 @@ static void ftrace_list_func(unsigned long ip, unsigned long parent_ip) | |||
90 | 91 | ||
91 | static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip) | 92 | static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip) |
92 | { | 93 | { |
93 | if (current->pid != ftrace_pid_trace) | 94 | if (!test_tsk_trace_trace(current)) |
94 | return; | 95 | return; |
95 | 96 | ||
96 | ftrace_pid_function(ip, parent_ip); | 97 | ftrace_pid_function(ip, parent_ip); |
@@ -153,7 +154,7 @@ static int __register_ftrace_function(struct ftrace_ops *ops) | |||
153 | else | 154 | else |
154 | func = ftrace_list_func; | 155 | func = ftrace_list_func; |
155 | 156 | ||
156 | if (ftrace_pid_trace >= 0) { | 157 | if (ftrace_pid_trace) { |
157 | set_ftrace_pid_function(func); | 158 | set_ftrace_pid_function(func); |
158 | func = ftrace_pid_func; | 159 | func = ftrace_pid_func; |
159 | } | 160 | } |
@@ -209,7 +210,7 @@ static int __unregister_ftrace_function(struct ftrace_ops *ops) | |||
209 | if (ftrace_list->next == &ftrace_list_end) { | 210 | if (ftrace_list->next == &ftrace_list_end) { |
210 | ftrace_func_t func = ftrace_list->func; | 211 | ftrace_func_t func = ftrace_list->func; |
211 | 212 | ||
212 | if (ftrace_pid_trace >= 0) { | 213 | if (ftrace_pid_trace) { |
213 | set_ftrace_pid_function(func); | 214 | set_ftrace_pid_function(func); |
214 | func = ftrace_pid_func; | 215 | func = ftrace_pid_func; |
215 | } | 216 | } |
@@ -239,7 +240,7 @@ static void ftrace_update_pid_func(void) | |||
239 | 240 | ||
240 | func = ftrace_trace_function; | 241 | func = ftrace_trace_function; |
241 | 242 | ||
242 | if (ftrace_pid_trace >= 0) { | 243 | if (ftrace_pid_trace) { |
243 | set_ftrace_pid_function(func); | 244 | set_ftrace_pid_function(func); |
244 | func = ftrace_pid_func; | 245 | func = ftrace_pid_func; |
245 | } else { | 246 | } else { |
@@ -1320,6 +1321,230 @@ static struct file_operations ftrace_notrace_fops = { | |||
1320 | .release = ftrace_notrace_release, | 1321 | .release = ftrace_notrace_release, |
1321 | }; | 1322 | }; |
1322 | 1323 | ||
1324 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
1325 | |||
1326 | static DEFINE_MUTEX(graph_lock); | ||
1327 | |||
1328 | int ftrace_graph_count; | ||
1329 | unsigned long ftrace_graph_funcs[FTRACE_GRAPH_MAX_FUNCS] __read_mostly; | ||
1330 | |||
1331 | static void * | ||
1332 | g_next(struct seq_file *m, void *v, loff_t *pos) | ||
1333 | { | ||
1334 | unsigned long *array = m->private; | ||
1335 | int index = *pos; | ||
1336 | |||
1337 | (*pos)++; | ||
1338 | |||
1339 | if (index >= ftrace_graph_count) | ||
1340 | return NULL; | ||
1341 | |||
1342 | return &array[index]; | ||
1343 | } | ||
1344 | |||
1345 | static void *g_start(struct seq_file *m, loff_t *pos) | ||
1346 | { | ||
1347 | void *p = NULL; | ||
1348 | |||
1349 | mutex_lock(&graph_lock); | ||
1350 | |||
1351 | p = g_next(m, p, pos); | ||
1352 | |||
1353 | return p; | ||
1354 | } | ||
1355 | |||
1356 | static void g_stop(struct seq_file *m, void *p) | ||
1357 | { | ||
1358 | mutex_unlock(&graph_lock); | ||
1359 | } | ||
1360 | |||
1361 | static int g_show(struct seq_file *m, void *v) | ||
1362 | { | ||
1363 | unsigned long *ptr = v; | ||
1364 | char str[KSYM_SYMBOL_LEN]; | ||
1365 | |||
1366 | if (!ptr) | ||
1367 | return 0; | ||
1368 | |||
1369 | kallsyms_lookup(*ptr, NULL, NULL, NULL, str); | ||
1370 | |||
1371 | seq_printf(m, "%s\n", str); | ||
1372 | |||
1373 | return 0; | ||
1374 | } | ||
1375 | |||
1376 | static struct seq_operations ftrace_graph_seq_ops = { | ||
1377 | .start = g_start, | ||
1378 | .next = g_next, | ||
1379 | .stop = g_stop, | ||
1380 | .show = g_show, | ||
1381 | }; | ||
1382 | |||
1383 | static int | ||
1384 | ftrace_graph_open(struct inode *inode, struct file *file) | ||
1385 | { | ||
1386 | int ret = 0; | ||
1387 | |||
1388 | if (unlikely(ftrace_disabled)) | ||
1389 | return -ENODEV; | ||
1390 | |||
1391 | mutex_lock(&graph_lock); | ||
1392 | if ((file->f_mode & FMODE_WRITE) && | ||
1393 | !(file->f_flags & O_APPEND)) { | ||
1394 | ftrace_graph_count = 0; | ||
1395 | memset(ftrace_graph_funcs, 0, sizeof(ftrace_graph_funcs)); | ||
1396 | } | ||
1397 | |||
1398 | if (file->f_mode & FMODE_READ) { | ||
1399 | ret = seq_open(file, &ftrace_graph_seq_ops); | ||
1400 | if (!ret) { | ||
1401 | struct seq_file *m = file->private_data; | ||
1402 | m->private = ftrace_graph_funcs; | ||
1403 | } | ||
1404 | } else | ||
1405 | file->private_data = ftrace_graph_funcs; | ||
1406 | mutex_unlock(&graph_lock); | ||
1407 | |||
1408 | return ret; | ||
1409 | } | ||
1410 | |||
1411 | static ssize_t | ||
1412 | ftrace_graph_read(struct file *file, char __user *ubuf, | ||
1413 | size_t cnt, loff_t *ppos) | ||
1414 | { | ||
1415 | if (file->f_mode & FMODE_READ) | ||
1416 | return seq_read(file, ubuf, cnt, ppos); | ||
1417 | else | ||
1418 | return -EPERM; | ||
1419 | } | ||
1420 | |||
1421 | static int | ||
1422 | ftrace_set_func(unsigned long *array, int idx, char *buffer) | ||
1423 | { | ||
1424 | char str[KSYM_SYMBOL_LEN]; | ||
1425 | struct dyn_ftrace *rec; | ||
1426 | struct ftrace_page *pg; | ||
1427 | int found = 0; | ||
1428 | int i, j; | ||
1429 | |||
1430 | if (ftrace_disabled) | ||
1431 | return -ENODEV; | ||
1432 | |||
1433 | /* should not be called from interrupt context */ | ||
1434 | spin_lock(&ftrace_lock); | ||
1435 | |||
1436 | for (pg = ftrace_pages_start; pg; pg = pg->next) { | ||
1437 | for (i = 0; i < pg->index; i++) { | ||
1438 | rec = &pg->records[i]; | ||
1439 | |||
1440 | if (rec->flags & (FTRACE_FL_FAILED | FTRACE_FL_FREE)) | ||
1441 | continue; | ||
1442 | |||
1443 | kallsyms_lookup(rec->ip, NULL, NULL, NULL, str); | ||
1444 | if (strcmp(str, buffer) == 0) { | ||
1445 | found = 1; | ||
1446 | for (j = 0; j < idx; j++) | ||
1447 | if (array[j] == rec->ip) { | ||
1448 | found = 0; | ||
1449 | break; | ||
1450 | } | ||
1451 | if (found) | ||
1452 | array[idx] = rec->ip; | ||
1453 | break; | ||
1454 | } | ||
1455 | } | ||
1456 | } | ||
1457 | spin_unlock(&ftrace_lock); | ||
1458 | |||
1459 | return found ? 0 : -EINVAL; | ||
1460 | } | ||
1461 | |||
1462 | static ssize_t | ||
1463 | ftrace_graph_write(struct file *file, const char __user *ubuf, | ||
1464 | size_t cnt, loff_t *ppos) | ||
1465 | { | ||
1466 | unsigned char buffer[FTRACE_BUFF_MAX+1]; | ||
1467 | unsigned long *array; | ||
1468 | size_t read = 0; | ||
1469 | ssize_t ret; | ||
1470 | int index = 0; | ||
1471 | char ch; | ||
1472 | |||
1473 | if (!cnt || cnt < 0) | ||
1474 | return 0; | ||
1475 | |||
1476 | mutex_lock(&graph_lock); | ||
1477 | |||
1478 | if (ftrace_graph_count >= FTRACE_GRAPH_MAX_FUNCS) { | ||
1479 | ret = -EBUSY; | ||
1480 | goto out; | ||
1481 | } | ||
1482 | |||
1483 | if (file->f_mode & FMODE_READ) { | ||
1484 | struct seq_file *m = file->private_data; | ||
1485 | array = m->private; | ||
1486 | } else | ||
1487 | array = file->private_data; | ||
1488 | |||
1489 | ret = get_user(ch, ubuf++); | ||
1490 | if (ret) | ||
1491 | goto out; | ||
1492 | read++; | ||
1493 | cnt--; | ||
1494 | |||
1495 | /* skip white space */ | ||
1496 | while (cnt && isspace(ch)) { | ||
1497 | ret = get_user(ch, ubuf++); | ||
1498 | if (ret) | ||
1499 | goto out; | ||
1500 | read++; | ||
1501 | cnt--; | ||
1502 | } | ||
1503 | |||
1504 | if (isspace(ch)) { | ||
1505 | *ppos += read; | ||
1506 | ret = read; | ||
1507 | goto out; | ||
1508 | } | ||
1509 | |||
1510 | while (cnt && !isspace(ch)) { | ||
1511 | if (index < FTRACE_BUFF_MAX) | ||
1512 | buffer[index++] = ch; | ||
1513 | else { | ||
1514 | ret = -EINVAL; | ||
1515 | goto out; | ||
1516 | } | ||
1517 | ret = get_user(ch, ubuf++); | ||
1518 | if (ret) | ||
1519 | goto out; | ||
1520 | read++; | ||
1521 | cnt--; | ||
1522 | } | ||
1523 | buffer[index] = 0; | ||
1524 | |||
1525 | /* we allow only one at a time */ | ||
1526 | ret = ftrace_set_func(array, ftrace_graph_count, buffer); | ||
1527 | if (ret) | ||
1528 | goto out; | ||
1529 | |||
1530 | ftrace_graph_count++; | ||
1531 | |||
1532 | file->f_pos += read; | ||
1533 | |||
1534 | ret = read; | ||
1535 | out: | ||
1536 | mutex_unlock(&graph_lock); | ||
1537 | |||
1538 | return ret; | ||
1539 | } | ||
1540 | |||
1541 | static const struct file_operations ftrace_graph_fops = { | ||
1542 | .open = ftrace_graph_open, | ||
1543 | .read = ftrace_graph_read, | ||
1544 | .write = ftrace_graph_write, | ||
1545 | }; | ||
1546 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | ||
1547 | |||
1323 | static __init int ftrace_init_dyn_debugfs(struct dentry *d_tracer) | 1548 | static __init int ftrace_init_dyn_debugfs(struct dentry *d_tracer) |
1324 | { | 1549 | { |
1325 | struct dentry *entry; | 1550 | struct dentry *entry; |
@@ -1347,6 +1572,15 @@ static __init int ftrace_init_dyn_debugfs(struct dentry *d_tracer) | |||
1347 | pr_warning("Could not create debugfs " | 1572 | pr_warning("Could not create debugfs " |
1348 | "'set_ftrace_notrace' entry\n"); | 1573 | "'set_ftrace_notrace' entry\n"); |
1349 | 1574 | ||
1575 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
1576 | entry = debugfs_create_file("set_graph_function", 0444, d_tracer, | ||
1577 | NULL, | ||
1578 | &ftrace_graph_fops); | ||
1579 | if (!entry) | ||
1580 | pr_warning("Could not create debugfs " | ||
1581 | "'set_graph_function' entry\n"); | ||
1582 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | ||
1583 | |||
1350 | return 0; | 1584 | return 0; |
1351 | } | 1585 | } |
1352 | 1586 | ||
@@ -1451,18 +1685,84 @@ ftrace_pid_read(struct file *file, char __user *ubuf, | |||
1451 | char buf[64]; | 1685 | char buf[64]; |
1452 | int r; | 1686 | int r; |
1453 | 1687 | ||
1454 | if (ftrace_pid_trace >= 0) | 1688 | if (ftrace_pid_trace == ftrace_swapper_pid) |
1455 | r = sprintf(buf, "%u\n", ftrace_pid_trace); | 1689 | r = sprintf(buf, "swapper tasks\n"); |
1690 | else if (ftrace_pid_trace) | ||
1691 | r = sprintf(buf, "%u\n", pid_nr(ftrace_pid_trace)); | ||
1456 | else | 1692 | else |
1457 | r = sprintf(buf, "no pid\n"); | 1693 | r = sprintf(buf, "no pid\n"); |
1458 | 1694 | ||
1459 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); | 1695 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); |
1460 | } | 1696 | } |
1461 | 1697 | ||
1698 | static void clear_ftrace_swapper(void) | ||
1699 | { | ||
1700 | struct task_struct *p; | ||
1701 | int cpu; | ||
1702 | |||
1703 | get_online_cpus(); | ||
1704 | for_each_online_cpu(cpu) { | ||
1705 | p = idle_task(cpu); | ||
1706 | clear_tsk_trace_trace(p); | ||
1707 | } | ||
1708 | put_online_cpus(); | ||
1709 | } | ||
1710 | |||
1711 | static void set_ftrace_swapper(void) | ||
1712 | { | ||
1713 | struct task_struct *p; | ||
1714 | int cpu; | ||
1715 | |||
1716 | get_online_cpus(); | ||
1717 | for_each_online_cpu(cpu) { | ||
1718 | p = idle_task(cpu); | ||
1719 | set_tsk_trace_trace(p); | ||
1720 | } | ||
1721 | put_online_cpus(); | ||
1722 | } | ||
1723 | |||
1724 | static void clear_ftrace_pid(struct pid *pid) | ||
1725 | { | ||
1726 | struct task_struct *p; | ||
1727 | |||
1728 | do_each_pid_task(pid, PIDTYPE_PID, p) { | ||
1729 | clear_tsk_trace_trace(p); | ||
1730 | } while_each_pid_task(pid, PIDTYPE_PID, p); | ||
1731 | put_pid(pid); | ||
1732 | } | ||
1733 | |||
1734 | static void set_ftrace_pid(struct pid *pid) | ||
1735 | { | ||
1736 | struct task_struct *p; | ||
1737 | |||
1738 | do_each_pid_task(pid, PIDTYPE_PID, p) { | ||
1739 | set_tsk_trace_trace(p); | ||
1740 | } while_each_pid_task(pid, PIDTYPE_PID, p); | ||
1741 | } | ||
1742 | |||
1743 | static void clear_ftrace_pid_task(struct pid **pid) | ||
1744 | { | ||
1745 | if (*pid == ftrace_swapper_pid) | ||
1746 | clear_ftrace_swapper(); | ||
1747 | else | ||
1748 | clear_ftrace_pid(*pid); | ||
1749 | |||
1750 | *pid = NULL; | ||
1751 | } | ||
1752 | |||
1753 | static void set_ftrace_pid_task(struct pid *pid) | ||
1754 | { | ||
1755 | if (pid == ftrace_swapper_pid) | ||
1756 | set_ftrace_swapper(); | ||
1757 | else | ||
1758 | set_ftrace_pid(pid); | ||
1759 | } | ||
1760 | |||
1462 | static ssize_t | 1761 | static ssize_t |
1463 | ftrace_pid_write(struct file *filp, const char __user *ubuf, | 1762 | ftrace_pid_write(struct file *filp, const char __user *ubuf, |
1464 | size_t cnt, loff_t *ppos) | 1763 | size_t cnt, loff_t *ppos) |
1465 | { | 1764 | { |
1765 | struct pid *pid; | ||
1466 | char buf[64]; | 1766 | char buf[64]; |
1467 | long val; | 1767 | long val; |
1468 | int ret; | 1768 | int ret; |
@@ -1480,18 +1780,37 @@ ftrace_pid_write(struct file *filp, const char __user *ubuf, | |||
1480 | return ret; | 1780 | return ret; |
1481 | 1781 | ||
1482 | mutex_lock(&ftrace_start_lock); | 1782 | mutex_lock(&ftrace_start_lock); |
1483 | if (ret < 0) { | 1783 | if (val < 0) { |
1484 | /* disable pid tracing */ | 1784 | /* disable pid tracing */ |
1485 | if (ftrace_pid_trace < 0) | 1785 | if (!ftrace_pid_trace) |
1486 | goto out; | 1786 | goto out; |
1487 | ftrace_pid_trace = -1; | 1787 | |
1788 | clear_ftrace_pid_task(&ftrace_pid_trace); | ||
1488 | 1789 | ||
1489 | } else { | 1790 | } else { |
1791 | /* swapper task is special */ | ||
1792 | if (!val) { | ||
1793 | pid = ftrace_swapper_pid; | ||
1794 | if (pid == ftrace_pid_trace) | ||
1795 | goto out; | ||
1796 | } else { | ||
1797 | pid = find_get_pid(val); | ||
1490 | 1798 | ||
1491 | if (ftrace_pid_trace == val) | 1799 | if (pid == ftrace_pid_trace) { |
1800 | put_pid(pid); | ||
1801 | goto out; | ||
1802 | } | ||
1803 | } | ||
1804 | |||
1805 | if (ftrace_pid_trace) | ||
1806 | clear_ftrace_pid_task(&ftrace_pid_trace); | ||
1807 | |||
1808 | if (!pid) | ||
1492 | goto out; | 1809 | goto out; |
1493 | 1810 | ||
1494 | ftrace_pid_trace = val; | 1811 | ftrace_pid_trace = pid; |
1812 | |||
1813 | set_ftrace_pid_task(ftrace_pid_trace); | ||
1495 | } | 1814 | } |
1496 | 1815 | ||
1497 | /* update the function call */ | 1816 | /* update the function call */ |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 1ca74c0cee6a..ea38652d631c 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -1209,6 +1209,12 @@ int trace_graph_entry(struct ftrace_graph_ent *trace) | |||
1209 | int cpu; | 1209 | int cpu; |
1210 | int pc; | 1210 | int pc; |
1211 | 1211 | ||
1212 | if (!ftrace_trace_task(current)) | ||
1213 | return 0; | ||
1214 | |||
1215 | if (!ftrace_graph_addr(trace->func)) | ||
1216 | return 0; | ||
1217 | |||
1212 | local_irq_save(flags); | 1218 | local_irq_save(flags); |
1213 | cpu = raw_smp_processor_id(); | 1219 | cpu = raw_smp_processor_id(); |
1214 | data = tr->data[cpu]; | 1220 | data = tr->data[cpu]; |
@@ -1217,6 +1223,9 @@ int trace_graph_entry(struct ftrace_graph_ent *trace) | |||
1217 | pc = preempt_count(); | 1223 | pc = preempt_count(); |
1218 | __trace_graph_entry(tr, data, trace, flags, pc); | 1224 | __trace_graph_entry(tr, data, trace, flags, pc); |
1219 | } | 1225 | } |
1226 | /* Only do the atomic if it is not already set */ | ||
1227 | if (!test_tsk_trace_graph(current)) | ||
1228 | set_tsk_trace_graph(current); | ||
1220 | atomic_dec(&data->disabled); | 1229 | atomic_dec(&data->disabled); |
1221 | local_irq_restore(flags); | 1230 | local_irq_restore(flags); |
1222 | 1231 | ||
@@ -1240,6 +1249,8 @@ void trace_graph_return(struct ftrace_graph_ret *trace) | |||
1240 | pc = preempt_count(); | 1249 | pc = preempt_count(); |
1241 | __trace_graph_return(tr, data, trace, flags, pc); | 1250 | __trace_graph_return(tr, data, trace, flags, pc); |
1242 | } | 1251 | } |
1252 | if (!trace->depth) | ||
1253 | clear_tsk_trace_graph(current); | ||
1243 | atomic_dec(&data->disabled); | 1254 | atomic_dec(&data->disabled); |
1244 | local_irq_restore(flags); | 1255 | local_irq_restore(flags); |
1245 | } | 1256 | } |
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index fce98898205a..a71bbe0a3631 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
@@ -507,13 +507,55 @@ extern unsigned long trace_flags; | |||
507 | /* Standard output formatting function used for function return traces */ | 507 | /* Standard output formatting function used for function return traces */ |
508 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 508 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
509 | extern enum print_line_t print_graph_function(struct trace_iterator *iter); | 509 | extern enum print_line_t print_graph_function(struct trace_iterator *iter); |
510 | |||
511 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
512 | /* TODO: make this variable */ | ||
513 | #define FTRACE_GRAPH_MAX_FUNCS 32 | ||
514 | extern int ftrace_graph_count; | ||
515 | extern unsigned long ftrace_graph_funcs[FTRACE_GRAPH_MAX_FUNCS]; | ||
516 | |||
517 | static inline int ftrace_graph_addr(unsigned long addr) | ||
518 | { | ||
519 | int i; | ||
520 | |||
521 | if (!ftrace_graph_count || test_tsk_trace_graph(current)) | ||
522 | return 1; | ||
523 | |||
524 | for (i = 0; i < ftrace_graph_count; i++) { | ||
525 | if (addr == ftrace_graph_funcs[i]) | ||
526 | return 1; | ||
527 | } | ||
528 | |||
529 | return 0; | ||
530 | } | ||
510 | #else | 531 | #else |
532 | static inline int ftrace_trace_addr(unsigned long addr) | ||
533 | { | ||
534 | return 1; | ||
535 | } | ||
536 | static inline int ftrace_graph_addr(unsigned long addr) | ||
537 | { | ||
538 | return 1; | ||
539 | } | ||
540 | #endif /* CONFIG_DYNAMIC_FTRACE */ | ||
541 | |||
542 | #else /* CONFIG_FUNCTION_GRAPH_TRACER */ | ||
511 | static inline enum print_line_t | 543 | static inline enum print_line_t |
512 | print_graph_function(struct trace_iterator *iter) | 544 | print_graph_function(struct trace_iterator *iter) |
513 | { | 545 | { |
514 | return TRACE_TYPE_UNHANDLED; | 546 | return TRACE_TYPE_UNHANDLED; |
515 | } | 547 | } |
516 | #endif | 548 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ |
549 | |||
550 | extern struct pid *ftrace_pid_trace; | ||
551 | |||
552 | static inline int ftrace_trace_task(struct task_struct *task) | ||
553 | { | ||
554 | if (ftrace_pid_trace) | ||
555 | return 1; | ||
556 | |||
557 | return test_tsk_trace_trace(task); | ||
558 | } | ||
517 | 559 | ||
518 | /* | 560 | /* |
519 | * trace_iterator_flags is an enumeration that defines bit | 561 | * trace_iterator_flags is an enumeration that defines bit |