diff options
Diffstat (limited to 'kernel')
| -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) |
