diff options
Diffstat (limited to 'kernel/trace/ftrace.c')
-rw-r--r-- | kernel/trace/ftrace.c | 74 |
1 files changed, 63 insertions, 11 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 10b1d7c1b1dd..eb57dc1ea097 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
@@ -49,6 +49,7 @@ static int last_ftrace_enabled; | |||
49 | 49 | ||
50 | /* set when tracing only a pid */ | 50 | /* set when tracing only a pid */ |
51 | struct pid *ftrace_pid_trace; | 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; |
@@ -1678,7 +1679,9 @@ ftrace_pid_read(struct file *file, char __user *ubuf, | |||
1678 | char buf[64]; | 1679 | char buf[64]; |
1679 | int r; | 1680 | int r; |
1680 | 1681 | ||
1681 | if (ftrace_pid_trace) | 1682 | if (ftrace_pid_trace == ftrace_swapper_pid) |
1683 | r = sprintf(buf, "swapper tasks\n"); | ||
1684 | else if (ftrace_pid_trace) | ||
1682 | r = sprintf(buf, "%u\n", pid_nr(ftrace_pid_trace)); | 1685 | r = sprintf(buf, "%u\n", pid_nr(ftrace_pid_trace)); |
1683 | else | 1686 | else |
1684 | r = sprintf(buf, "no pid\n"); | 1687 | r = sprintf(buf, "no pid\n"); |
@@ -1686,19 +1689,43 @@ ftrace_pid_read(struct file *file, char __user *ubuf, | |||
1686 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); | 1689 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); |
1687 | } | 1690 | } |
1688 | 1691 | ||
1689 | static void clear_ftrace_pid_task(struct pid **pid) | 1692 | static void clear_ftrace_swapper(void) |
1690 | { | 1693 | { |
1691 | struct task_struct *p; | 1694 | struct task_struct *p; |
1695 | int cpu; | ||
1692 | 1696 | ||
1693 | do_each_pid_task(*pid, PIDTYPE_PID, p) { | 1697 | get_online_cpus(); |
1698 | for_each_online_cpu(cpu) { | ||
1699 | p = idle_task(cpu); | ||
1694 | clear_tsk_trace_trace(p); | 1700 | clear_tsk_trace_trace(p); |
1695 | } while_each_pid_task(*pid, PIDTYPE_PID, p); | 1701 | } |
1696 | put_pid(*pid); | 1702 | put_online_cpus(); |
1703 | } | ||
1697 | 1704 | ||
1698 | *pid = NULL; | 1705 | static void set_ftrace_swapper(void) |
1706 | { | ||
1707 | struct task_struct *p; | ||
1708 | int cpu; | ||
1709 | |||
1710 | get_online_cpus(); | ||
1711 | for_each_online_cpu(cpu) { | ||
1712 | p = idle_task(cpu); | ||
1713 | set_tsk_trace_trace(p); | ||
1714 | } | ||
1715 | put_online_cpus(); | ||
1699 | } | 1716 | } |
1700 | 1717 | ||
1701 | static void set_ftrace_pid_task(struct pid *pid) | 1718 | static void clear_ftrace_pid(struct pid *pid) |
1719 | { | ||
1720 | struct task_struct *p; | ||
1721 | |||
1722 | do_each_pid_task(pid, PIDTYPE_PID, p) { | ||
1723 | clear_tsk_trace_trace(p); | ||
1724 | } while_each_pid_task(pid, PIDTYPE_PID, p); | ||
1725 | put_pid(pid); | ||
1726 | } | ||
1727 | |||
1728 | static void set_ftrace_pid(struct pid *pid) | ||
1702 | { | 1729 | { |
1703 | struct task_struct *p; | 1730 | struct task_struct *p; |
1704 | 1731 | ||
@@ -1707,6 +1734,24 @@ static void set_ftrace_pid_task(struct pid *pid) | |||
1707 | } while_each_pid_task(pid, PIDTYPE_PID, p); | 1734 | } while_each_pid_task(pid, PIDTYPE_PID, p); |
1708 | } | 1735 | } |
1709 | 1736 | ||
1737 | static void clear_ftrace_pid_task(struct pid **pid) | ||
1738 | { | ||
1739 | if (*pid == ftrace_swapper_pid) | ||
1740 | clear_ftrace_swapper(); | ||
1741 | else | ||
1742 | clear_ftrace_pid(*pid); | ||
1743 | |||
1744 | *pid = NULL; | ||
1745 | } | ||
1746 | |||
1747 | static void set_ftrace_pid_task(struct pid *pid) | ||
1748 | { | ||
1749 | if (pid == ftrace_swapper_pid) | ||
1750 | set_ftrace_swapper(); | ||
1751 | else | ||
1752 | set_ftrace_pid(pid); | ||
1753 | } | ||
1754 | |||
1710 | static ssize_t | 1755 | static ssize_t |
1711 | ftrace_pid_write(struct file *filp, const char __user *ubuf, | 1756 | ftrace_pid_write(struct file *filp, const char __user *ubuf, |
1712 | size_t cnt, loff_t *ppos) | 1757 | size_t cnt, loff_t *ppos) |
@@ -1737,11 +1782,18 @@ ftrace_pid_write(struct file *filp, const char __user *ubuf, | |||
1737 | clear_ftrace_pid_task(&ftrace_pid_trace); | 1782 | clear_ftrace_pid_task(&ftrace_pid_trace); |
1738 | 1783 | ||
1739 | } else { | 1784 | } else { |
1740 | pid = find_get_pid(val); | 1785 | /* swapper task is special */ |
1786 | if (!val) { | ||
1787 | pid = ftrace_swapper_pid; | ||
1788 | if (pid == ftrace_pid_trace) | ||
1789 | goto out; | ||
1790 | } else { | ||
1791 | pid = find_get_pid(val); | ||
1741 | 1792 | ||
1742 | if (pid == ftrace_pid_trace) { | 1793 | if (pid == ftrace_pid_trace) { |
1743 | put_pid(pid); | 1794 | put_pid(pid); |
1744 | goto out; | 1795 | goto out; |
1796 | } | ||
1745 | } | 1797 | } |
1746 | 1798 | ||
1747 | if (ftrace_pid_trace) | 1799 | if (ftrace_pid_trace) |